proguard 提示Warning: can't find referenced field/method '...' in library class ...等問題

        最近用到maven+proguard來做java代碼混淆,在添加完pom.xml以及配置文件proguard.conf後遇到了三個問題。

1.Warning: can't find referenced field/method '...' in library class (or: can't find referenced classes..)

2.Warning: library class ... depends on program class ...

3.Warning: class file ... unexpectedly contains class ...

前兩個問題最後用了一種方法解決,所以相當於兩個問題,我主要說1和3.

官網上(http://proguard.sourceforge.net/index.html#/manual/examples.html),關於第一個問題的描述是:

A program class is referring to a field or a method that is missing from a library class. The warning lists both the referencing class and the missing referenced class member. Your compiled class files are inconsistent with the libraries. You may need to recompile the class files, or otherwise upgrade the libraries to consistent versions.

【android】 If you're developing for Android and ProGuard complains that it can't find a method that is only available in a recent version of the Android run-time, you should change the build target in your project.properties file or build.gradle file to that recent version. You can still specify a different minSdkVersion and a different targetSdkVersion in your AndroidManifest.xml file.


Alternatively, you may get away with ignoring the inconsistency with the options -ignorewarnings or even -dontwarn. For instance, you can specify "-dontwarn mypackage.MyInconsistentClass".


Finally, should your program classes reside in the same packages as library classes and should they refer to their package visible class members, then you should also specify the -dontskipnonpubliclibraryclassmembers option.

大概意思是程序裏面用到了庫裏的類,但庫裏沒有這些類。所以警告了,同時,可以用命令來忽略這些警告。

只是忽略警告的話,實際上還是沒有解決問題,後來查找了一些資料,發現是proguard在混淆的時候,把庫裏的jar包也混淆了,導致程序找不到這些類。於是解決方法就簡單了,只需要在proguard.conf配置中用keep命令保留報警的類就行了。但是通常報警的類有成百上千個,不可能一個個保留,有一個簡單的方法是隻要類的路徑前面有相同的根,就可以保留一個總的達到保留下面所有類的目的。比如:

#消除警告 Warning: can't find superclass or interface#Warning: can't find referenced class
-dontwarn org.springframework.**
-keep class org.springframework.** { *;}
-dontwarn org.codehaus.**
-keep class org.codehaus.** { *;}-dontwarn org.apache.**-keep class org.apache.** { *;} 

第2個問題與第一個類似,也是保留相應的類就可以了。

官網關於第三個問題的描述是:

The given class file contains a definition for the given class, but the directory name of the file doesn't correspond to the package name of the class. ProGuard will accept the class definition, but the current implementation will not write out the processed version. Please make sure your input classes are packaged correctly. Notably, class files that are in the WEB-INF/classes directory in a war should be packaged in a jar and put in the WEB-INF/lib directory. If you don't mind these classes not being written to the output, you can specify the -ignorewarnings option, or even the -dontwarn option.

大概意思是類文件的目錄名跟類的包名不一致導致了警報,需要確保目錄和包名一樣纔行。特別是WEB-INF/classes目錄下的文件需要打成jar包放到WEB-INF/lib 目錄下。

我的這個問題正是出在WEB-INF/classes/....目錄這兒,然後我把classes下的類打包放到了lib下,結果然並卵。後來又試了試,發現因爲proguard會同時讀取classes下的類和lib下的jar包,jar包像上面說的一樣是沒有問題的,但是classes下的類目錄必然要帶着classes,然而類名卻不是以WEB-INF.classes開頭,所以這個警報不可避免會出現。最後消除警報是在-injars裏面添加過濾把classes下的類都過濾掉,還有別忘了把jar包添加到lib裏。

-injars D:/OrbitService/target/OrbitService.war(!WEB-INF/classes/**)


參考:

1.http://blog.csdn.net/u_xtian/article/details/7495023

2.http://sourceforge.net/p/proguard/discussion/182456/thread/f65a13f2/

3.http://sourceforge.net/p/proguard/discussion/182456/thread/19d2b6bd/

4.http://sourceforge.net/p/proguard/discussion/182456/thread/171d59bb/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章