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/

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