2015-10-17 40 views
9

我試着混淆我們的web應用程序,它使用spring,jaxb並依賴註釋和大量反射。 我應用了很多在互聯網上發現的食譜來保留一些類,屬性,註釋和枚舉。 但枚舉仍然有問題。我能保存枚舉常量應用配置從http://proguard.sourceforge.net/manual/examples.html#enumerations如何知道proguard保持枚舉常量和字段

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

在它看起來像工作的解決方案,不斷保存,所以(Class.getEnumConstants())乍一看返回值的正確的列表。 但是,當我嘗試通過任何名稱檢索字段時,我得到了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()); 
    } 
} 

我精確地落在變成 「不可能的」 分支。我認爲這將是很容易理解的看調試會話的截圖(有也列constants): Screenshot of debug session1

如果我嘗試獲得fields,它們列出混淆爲A,B,C,d,E,F: Screenshot of 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); 
} 

所以,我的問題是如何,我可以完全保持公共枚舉從混淆?在這兩種情況下 - 使用其常量(class.getEnumConstants())和字段(class.getFields())。

回答

19

感謝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); 
} 
+0

對於任何遇到此問題並希望與ant等效的人:添加_ _ proguard任務。 –

+0

我想你談論'maven'任務配置?在最初的問題上沒有關於maven的內容。我使用'gradle',但它也超出了範圍。所以,答案中提供的所有配置都屬於'proguard.conf'語法。 – Hubbitus

+0

Hubbitus是的,但是我試圖解決這個問題,但是使用ant(而不是maven),而不是直接使用proguard,我發現這個答案是第三個鏈接。兩者之間的翻譯並不是很明顯,至少不是我,所以我添加了一條評論,以便任何在我的條件下發現此內容的人也將獲得更多信息。絕不意味着你的答案不正確或不完整。我很遺憾,如果那是你所做的推斷。 –

4

這對我工作的罰款。

-keep public enum com.company.appname.**{ 
    *; 
} 

其中**是包裝和子包裝。