Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proguard warnings despite kept classes

I'm using Proguard to shrink my code. My strategy is to enable it and then follow the warnings to keep anything it complains about. If there are outside libraries, I try to follow the Proguard instructions the authors make available. Many instructions include a -dontwarn flag. If I disable the -dontwarn flag, I will get warnings. If we are keeping most classes via -keep flag, why do warnings still come up? Example:

-keep class javax.** { *; }

# for butterknife
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; }

-keepclasseswithmembernames class * {
    @butterknife.* <fields>;
}

-keepclasseswithmembernames class * {
    @butterknife.* <methods>;
}

Warning:butterknife.internal.ButterKnifeProcessor: can't find referenced class javax.annotation.processing.AbstractProcessor
Warning:butterknife.internal.ButterKnifeProcessor: can't find referenced class javax.annotation.processing.ProcessingEnvironment
Warning:butterknife.internal.ButterKnifeProcessor: can't find referenced class javax.lang.model.element.TypeElement
Warning:butterknife.internal.ButterKnifeProcessor: can't find referenced class javax.lang.model.element.Element
Warning:butterknife.internal.ButterKnifeProcessor: can't find referenced class javax.annotation.processing.Filer
Warning:butterknife.internal.ButterKnifeProcessor: can't find referenced class javax.tools.JavaFileObject
...
like image 388
Vas Avatar asked Apr 05 '16 14:04

Vas


People also ask

How to ignore warnings in ProGuard?

There is no option to switch off these warnings. The standard Android build process automatically specifies the input jars for you. There may not be an easy way to filter them to remove these warnings. You could remove the duplicate resource files manually from the input and the libraries.

Does ProGuard remove unused classes?

Shrinking Options By default, ProGuard shrinks the code: it removes all unused classes and class members.

How do you keep a class in ProGuard?

-keepclassmembernames. This is the most permissive keep directive; it lets ProGuard do almost all of its work. Unused classes are removed, the remaining classes are renamed, unused members of those classes are removed, but then the remaining members keep their original names.

What is Dontwarn in ProGuard?

If your code works fine without the missing classes, you can suppress the warnings with '-dontwarn' options. (


1 Answers

There are many warnings in ProGuard meaning different things. This particular one:

Warning:A: can't find referenced class B

Means that while ProGuard was processing class A it encountered reference to class B. But class B wasn't included as a source (-injars class_path) or as a library (-libraryjars class_path).

First note that for this particular warning in case of standard Android build chain adding -keep rules will not help. ProGuard transitively keeps referenced code.

This warning can happen for several reasons. Often a library X can contain code that uses another library Y. And X uses Y optionally - only when Y is present on the classpath, X doesn't enforce presence of Y. This way ProGuard is unable to find classes from Y. To get rid of the warnings you have to either add Y as a dependency or ignore the relevant warnings.

In case of ButterKnife the situation is slightly different. Butterknife uses annotation processing. And it contains both the library and annotation processor in one dependency (latest version 7.0.1). So class butterknife.internal.ButterKnifeProcessor is still present in the compiled classes (even though it's work is already finished - used during java compilation). And ProGuard tries to process it. ProGuard fails to find the missing classes because they were used only during annotation processing and are not present for ProGuard processing. In this case it's really necessary to ignore the warnings.

like image 91
Tomik Avatar answered Sep 27 '22 23:09

Tomik