如何告诉proguard保持枚举常量和字段

Hub*_*tus 20 java obfuscation proguard

我试图模糊我们的web应用程序,它使用spring,jaxb并依赖于注释和反射.我在互联网上应用了许多食谱来保存一些类,属性,注释和枚举.但是枚举仍有问题.我可以保存枚举常量应用来自http://proguard.sourceforge.net/manual/examples.html#enumerations的配置:

-keepclassmembers,allowoptimization enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}
Run Code Online (Sandbox Code Playgroud)

乍一看,它看起来像工作解决方案和常量保留,因此(Class.getEnumConstants())返回正确的值列表.但是当我尝试通过任何名称检索字段时,我得到了NoSuchFieldException.

问题来自jaxb反射导航器,请看代码:

public Field[] getEnumConstants(Class clazz) {
    try {
        Object[] values = clazz.getEnumConstants();
        Field[] fields = new Field[values.length];
        for (int i = 0; i < values.length; i++) {
            fields[i] = clazz.getField(((Enum) values[i]).name());
        }
        return fields;
    } catch (NoSuchFieldException e) {
        // impossible
        throw new NoSuchFieldError(e.getMessage());
    }
}
Run Code Online (Sandbox Code Playgroud)

我完全陷入"不可能"的分支.我认为查看调试会话截图(还列出了常量)很容易理解: debug session1的屏幕截图

如果我尝试获取字段,它们会被混淆为a,b,c,d,e,f: debug session2的屏幕截图

我的proguard配置现在看起来像(删除一些库列表和kipp关于proguard抱怨的特定类,字段和方法):

-injars  core-3.15.rc5.6.jar
-outjars core-3.15.rc5.6.proguard.jar

-libraryjars <java.home>/lib/rt.jar

-libraryjars ... # Other libs listed, strip out for shortness

-printmapping core-3.15.rc5.6.proguard.map

-keep public class ru.rlh.egais.portal.backend.controller.rest.**
-keep public class ru.rlh.egais.portal.backend.integration.soap.service.**

# http://midgetontoes.com/blog/2015/06/26/tips-for-using-proguard-with-spring-framework
-optimizations !class/marking/final

-adaptresourcefilecontents **.properties,META-INF/MANIFEST.MF,META-INF/spring.*,spring/*

-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
# Also tried:
# -keepattributes **

-allowaccessmodification
-dontshrink
-dontoptimize
-dontusemixedcaseclassnames
-keepdirectories
-keep @org.springframework.transaction.annotation.Transactional class *
-keep @org.springframework.stereotype.Service class *
-keep @org.springframework.stereotype.Repository class *
-keep @org.springframework.stereotype.Controller class *
-keep @org.springframework.stereotype.Component class *
-keep @org.springframework.beans.factory.annotation.Autowired class *
-keep @org.springframework.web.bind.annotation.ResponseBody class *
-keep @org.springframework.web.bind.annotation.RequestMapping class *
-keep @org.springframework.stereotype.Repository class *
-keep @javax.annotation.Resource class *
-keep @org.springframework.cache.annotation.EnableCaching class *
-keep @org.springframework.context.annotation.Configuration class *

-keepclassmembers class * {
    @org.springframework.beans.factory.annotation.* *;
    @org.springframework.beans.factory.annotation.Qualifier *;
    @org.springframework.beans.factory.annotation.Value *;
    @org.springframework.beans.factory.annotation.Required *;
    @org.springframework.context.annotation.Bean *;
    @javax.annotation.PostConstruct *;
    @javax.annotation.PreDestroy *;
    @org.aspectj.lang.annotation.AfterReturning *;
    @org.aspectj.lang.annotation.Pointcut *;
    @org.aspectj.lang.annotation.AfterThrowing *;
    @org.aspectj.lang.annotation.Around *;
}

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}
Run Code Online (Sandbox Code Playgroud)

那么,我的问题是如何完全保持公共枚举不被混淆?在这两种情况下 - 使用其常量(class.getEnumConstants())和字段(class.getFields()).

Hub*_*tus 51

感谢http://sourceforge.net/p/proguard/discussion/182455/thread/1c28f199/我找到了我的问题的解决方案(<⁠fields>必须添加):

-keepclassmembers class * extends java.lang.Enum {
    <fields>;
    public static **[] values();
    public static ** valueOf(java.lang.String);
}
Run Code Online (Sandbox Code Playgroud)


Jom*_*oma 10

这对我来说很好.

-keep public enum com.company.appname.**{
    *;
}
Run Code Online (Sandbox Code Playgroud)

其中**是包和子包.