如何告诉混淆器保留枚举常量和字段
How to tell proguard to keep enum constants and fields
我尝试混淆我们的 Web 应用程序,它使用 spring、jaxb 并严重依赖注释和反射。
我应用了在互联网上找到的许多食谱来保留一些 类、属性、注释和枚举。
但是枚举仍然有问题。我已经能够保留枚举常量应用来自 http://proguard.sourceforge.net/manual/examples.html#enumerations:
的配置
-keepclassmembers,allowoptimization enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
乍一看,它看起来像是有效的解决方案并保留了常量,因此 (Class.getEnumConstants()) return 正确的值列表。
但是当我尝试通过名称中的任何一个检索字段时,我得到了 NoSuchFieldException。
问题来自jaxb reflection navigator,请看代码:
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());
}
}
我完全属于 "impossible" 分支。我认为看调试会话截图会很容易理解(也列出了constants):
如果我尝试获取 fields,它们会被混淆为 a、b、c、d、e、f:
我的 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);
}
那么,我的问题是如何才能完全防止 public 枚举被混淆?在这两种情况下 - 使用其常量 (class.getEnumConstants()) and fields (class.getFields()).
感谢http://sourceforge.net/p/proguard/discussion/182455/thread/1c28f199/ I found solution for my question (<fields>必须加):
-keepclassmembers class * extends java.lang.Enum {
<fields>;
public static **[] values();
public static ** valueOf(java.lang.String);
}
这对我来说很好。
-keep public enum com.company.appname.**{
*;
}
其中 ** 是包和子包。
我尝试混淆我们的 Web 应用程序,它使用 spring、jaxb 并严重依赖注释和反射。 我应用了在互联网上找到的许多食谱来保留一些 类、属性、注释和枚举。 但是枚举仍然有问题。我已经能够保留枚举常量应用来自 http://proguard.sourceforge.net/manual/examples.html#enumerations:
的配置-keepclassmembers,allowoptimization enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
乍一看,它看起来像是有效的解决方案并保留了常量,因此 (Class.getEnumConstants()) return 正确的值列表。 但是当我尝试通过名称中的任何一个检索字段时,我得到了 NoSuchFieldException。
问题来自jaxb reflection navigator,请看代码:
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());
}
}
我完全属于 "impossible" 分支。我认为看调试会话截图会很容易理解(也列出了constants):
如果我尝试获取 fields,它们会被混淆为 a、b、c、d、e、f:
我的 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);
}
那么,我的问题是如何才能完全防止 public 枚举被混淆?在这两种情况下 - 使用其常量 (class.getEnumConstants()) and fields (class.getFields()).
感谢http://sourceforge.net/p/proguard/discussion/182455/thread/1c28f199/ I found solution for my question (<fields>必须加):
-keepclassmembers class * extends java.lang.Enum {
<fields>;
public static **[] values();
public static ** valueOf(java.lang.String);
}
这对我来说很好。
-keep public enum com.company.appname.**{
*;
}
其中 ** 是包和子包。