开发者

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 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜