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
...
There are many warnings in ProGuard meaning different things. This particular one:
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.