29

I'm working on a library that is distributed as a java jar, and I'm running proguard on it in such a way as to only leave the required interfaces exposed. I have a configuration class with a bunch of member variables and some enum defines. My proguard script preserves the member variables fine, however, the enum definitions are being obfuscated. I've tried everything I can think of to force proguard to retain these internally defined and public enums, but I can't get it to work.

Right now I'm using:

-keep public class com.stuff.MyConfigObject {
    public *;
}

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

If I try:

-keep public enum com.stuff.MyConfigObject.MyEnum

I get an ambiguous error: "Note: the configuration refers to the unknown class 'com.stuff.MyConfigObject.MyEnum'"

Thanks for the help!

Jesse
  • 403
  • 1
  • 5
  • 5

2 Answers2

45

Try com.stuff.MyConfigObject$MyEnum instead. The Proguard class specification expects $ as the separator for inner classes.

Actually, for what you want maybe the best option is something like this:

-keep public enum com.stuff.MyConfigObject$** {
    **[] $VALUES;
    public *;
}

This will keep only the required members for all enums nested within MyConfigObject - the required members being the $VALUES[] array (see this question for an explanation) and any public members of the enum. Any other members (e.g. private fields methods) will not be kept.


As noted by Jesse and myself in the comments - since you are processing a library, you must also add the -keepAttributes option. From the reference guide:

For example, you should at least keep the Exceptions, InnerClasses, and Signature attributes when processing a library.

Kevin K
  • 9,344
  • 3
  • 37
  • 62
  • Thanks that has gotten me a lot closer! However, the resulting .jar is a bit weird. The class files for the enums are there, and everything looks OK, but in Eclipse, none of the members can be used. Code completion shows them correctly, but compilation keeps failing with "MyEnum cannot be resolved or is not a field." I'm using proguard 4.4. – Jesse Jun 09 '11 at 14:24
  • 2
    I found if you add `-keepAttributes **` it will work. Not sure which particular attribute(s) must be kept, but with the [Proguard reference](http://proguard.sourceforge.net/manual/usage.html#keepattributes) and some experimentation I bet you could figure it out. – Kevin K Jun 09 '11 at 20:47
  • 3
    Thanks for the lead, I found this in the docs for -keepattributes : "For example, you should at least keep the Exceptions, InnerClasses, and Signature attributes when processing a library." – Jesse Jun 13 '11 at 14:34
  • Ah, I missed that sentence. Good to know. – Kevin K Jun 14 '11 at 00:40
  • For me `-keep enum com.example.**$** { **[] $VALUES; public *; }` is working – Pierre Jul 04 '19 at 12:39
2

to keep all internal enums try this:

-keep class * {
    public enum **;
}

it saves me from writing every of 123 enum in proguard config.

Also, don't forget -keepAttributes if you are processing a library

igork
  • 568
  • 7
  • 8