don't keep super class's public method in proguard - proguard

I have class A , and class B extends class A.
My proguard config is :
-keep public class B {
public <methods>;
}
I just want to keep the public methods in B , but proguard keep the public methods in A too.
Does anyone know how to reslove it ?
thanks ~

You'll have to enumerate the methods. Semantically, public methods of super classes are public methods in their subclasses too, so ProGuard keeps them if you use a wildcard..

Related

Typescript Abstract Class Method Access Derived Class Property

abstract class MyClass() {
protected static foo: Array<number>;
protected static doWorkOnFoo(): void {
let x: number = 0;
for (let f of | what goes here? this? self?|.foo) {
x = x + foo;
}
}
}
When implementing an abstract class, and wanting derived classes to have a static property and a static method that operates on those properties, how would one access those in the abstract class so that the derived class can just use that method?
I know this can be worked around by just setting a default value on the static property and using this, but this sparked my interested and I'm curious to know if there's some way to access generic derived class or something from an abstract class in TS.
Thanks in advance!
EDIT:
While I wasn't able to find exactly what I was looking for (see comments), a workable solution is to change the signature of the doWorkOnFoo() method to the following:
protected static doWorkOnFoo(): (typeof MyClass) => void;
Since it is already an abstract class it can take a derived class as an argument and then reference the derived class's static properties.

declaring a method as optional in abstract class

As far as I've understood in Dart is possible to use abstract classes to declare "interfaces" or "protocols" (if you come from objective-c).
Anyway I'm having trouble in finding a way to declare an optional method in the abstract class/interface.
If I declare a method in the abstract class A, and let the concrete class B implement A, I get a warning in the compiler.
I'd like to be able to declare a method as optional or at least to provide a default implementation without needing to "re-declare" it in a class that implements my interface.
abstract class A{
void abstractMethod();
}
class B implements A{
//not implementing abstract method here gives a warning
}
That's not how interfaces work. If your class states to implement an interface, then this is what it has to do.
You can split the interface
abstract class A {
void abstractMethod();
}
abstract class A1 extends A {
void optionalMethod();
}
class B implements A {
//not implementing abstract method here gives a warning
}
only when it states to implement A1 it has to implement optionalMethod.
Alternatively you can extend the abstract class
abstract class A{
void abstractMethod();
void optionalMethod(){};
}
class B extends A {
//not implementing abstract method here gives a warning
}
then only abstractMethod needs to be overridden because A doesn't provide an implementation.
Abstract methods defined in classes cannot be marked as optional. (At least not in the regular Dart language, I don't know of annotations that might support something like this.)
Any class that implements an interface must provide an implementation of all abstract methods, but, those method implementations may trivially throw an error to indicate that the method is not available.
Throw UnimplementedError if the implementing class is incomplete and the proper implementation is to be added later
Throw UnsupportedError if the implementing class does not intend to implement the method.
Note that UnimplementedError implements UnsupportedError.
Obviously you have to be judicious about what you choose to not implement. If it's in code that is not intended to be shared you can get away only implementing methods that you explicitly know are required. If it's in a library package intended to be shared with others you would need a good reason to not implement a method, and that reason should be well documented.
Example code:
abstract class A {
void abstractMethod();
}
class B implements A {
void abstractMethod() { throw new UnimplementedError(...); }
// or
void abstractMethod() { throw new UnsupportedError(...); }
}
See:
https://api.dartlang.org/stable/1.18.1/dart-core/UnimplementedError-class.html
https://api.dartlang.org/stable/1.18.1/dart-core/UnsupportedError-class.html

How to exclude specific methods from a "keep" rule in ProGuard?

I'm running ProGuard on a library. To keep public methods and attributes from shrinkage and obfuscation, I'm using this rule:
-keep public class com.company.project.** {
public protected <fields>;
public protected <methods>;
}
I need to make a few exceptions to this rule - methods that I actually need to be shrinked/obfuscated regularly by ProGuard. Is that possible? What would be the syntax for that?

How to keep an outer class while obfuscating the inner classes

I have a class that looks like this:
public class MyClass {
private class MyInnerClass {
public void someFunc() { }
}
public void usefulMethod() {
... some stuff...
nativeUsefulMethod();
}
private native void nativeUsefulMethod();
}
I need to keep the method names of all native functions, as well as the classes containing them, in order for the native code to work properly. Seems like no problem:
-keepnames class * {
native <methods>;
}
When I look at the resulting jar, I see that MyClass and nativeUsefulMethod() remain, while usefulMethod() has been obfuscated. Good. However, the inner class is still named "MyClass$MyInnerClass". It contains no native methods, so I would expect it to be called "MyClass$a" or just "a".
I tested changing "-keepnames" to "-keepclassmembernames", and the class names of both get obfuscated. It's definitely this directive that's keeping the inner class name. Is there a way to obfuscate the outer, but not the inner class name?
The proper configuration for native methods is:
-keepclasseswithmembernames class * {
native <methods>;
}
See the ProGuard manual > Examples > Processing native methods

Singleton subclass

I have an abstract base class and an implementation class like:
public abstract class Base
{
public Base getInstance( Class<? extends Base> clazz )
{
//expected to return a singleton instance of clazz's class
}
public abstract absMeth();
}
public A extends Base
{
//expected to be a singleton
}
In this example I can make A to be a singleton and even write getInstance in Base to return a singleton object of A for every call, doing this way:
public abstract class Base
{
public Base getInstance( Class<? extends Base> clazz )
{
try
{
return clazz.getDeclaredMethod("getInstance").invoke(null,null);
}
}
public abstract void absMeth();
}
public A extends Base
{
private static A inst;
private A(){}
public static A getInstance( )
{
if( inst!= null)
inst = new A();
return inst;
}
public void absMeth(){
//...
}
}
But my concern is how do I ensure that if somebody writes another class class B extends Base it should also be a singleton and it necessarily implements a static method called getInstance?
In other words I need to enforce this as a specification for all classes extending with the Base class.
You cannot trust classes that extend you to create a single instance of themselves1: even if you could somehow ensure that they all implement getInstance, there is no way to tell that inside that method they check inst before constructing a new instance of themselves.
Stay in control of the process: create a Map<Class,Base>, and instantiate the class passed in through reflection2. Now your code can decide whether to create an instance or not, without relying on the getInstance of a subclass.
1 A popular saying goes, "If you want a job done right, do it yourself."
2 Here is a link describing a solution based on setAccessible(true)
Singleton is a design pattern, not a language feature. It is pretty much impossible to somehow enforce it on the inheritance tree through syntax.
It certainly is possible to require all subclasses to implement a method by declaring it abstract but there is no way to control implementation details. Singleton is all about implementation details.
But why is this a concern at all? Do not make your app dependant on internal details of someone else's code. It is Bad Design™ and having this issue is a sure sign of it. Code against a well-defined interface and avoid relying on internal details.