How to keep classes containing specific members?
I want to keep only classes, which contain methods annotated with @Keep
, and these methods.
These methods (and owning classes) should be kept even if they are unused.
What I write in .pro-file is:
-keepclassmembers class * {
@Keep *;
}
-keepclasseswithmembers class * {
@Keep *;
}
But it shrinks out classes with @Keep methods if they are unused.
Then I try this:
-keep class * {
@Keep *;
}
it just keeps all the classes.
So, what should I write in .pro-file?
Update 1: example Thanks for your answer. But I already use fully-qualified annotation names and include JARs with annotations, but it doesn't do what I want. So, I've prepared a sample.
I have 2 JARs:
example.jar/
example/
code/
more/
开发者_JAVA百科 A.class
lib.jar/
example/
lib/
Keep.class
A.java:
package example.code.more;
import example.lib.*;
public class A {
@Keep
void foo() {}
}
Keep.java:
package example.lib;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.CLASS)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
public @interface Keep {
}
Proguard config, example.pro:
-injars example.jar
-injars lib.jar
-outjars obfuscated.jar
-libraryjars <java.home>/lib/rt.jar
-printmapping rt.map
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable
-printseeds
-overloadaggressively
-dontoptimize
-keeppackagenames example.lib.**
-keepattributes *Annotation*
-keepclassmembers class * extends java.lang.Enum {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class example.lib.* { *; }
-keep class * extends java.lang.annotation.Annotation { *; }
-keepclassmembers class * {
@example.lib.Keep *;
}
-keepclasseswithmembers class * {
@example.lib.Keep *;
}
See, package names are correct and all the JARs are included.
Resulting map-file:
example.lib.Keep -> example.lib.Keep:
So, A.class gets removed. What am I doing wrong?
Like in examples/annotations/lib/annotations.pro in the ProGuard distribution, you should specify fully qualified names. Furthermore, the option -keepclasseswithmembers doesn't combine well with the "*" wildcard -- use the "<methods>" wildcard instead:
-keepclasseswithmembers class * {
@proguard.annotation.Keep <methods>;
}
You also mustn't forget to read the jar that contains the annotation classes:
-libraryjars annotations.jar
精彩评论