ProGuard configuration for Guava with obfuscation and optimization

自闭症网瘾萝莉.ら 提交于 2019-11-28 03:15:51
Jonik

As of Guava 17.0, this is what I needed in ProGuard config:

-dontwarn javax.annotation.**
-dontwarn javax.inject.**
-dontwarn sun.misc.Unsafe

Otherwise build fails with warnings like:

Warning: com.google.common.base.Absent: 
   can't find referenced class javax.annotation.Nullable

(That's because Guava uses annotations that are not part of Android runtime (android.jar). In this case it's fine to just mute the warnings.)

If you are using Gradle as the build tool, the above proguard-project.txt and the following in build.gradle produces an optimised and obfuscated APK while using Guava.

buildTypes {
    release {
        minifyEnabled true
        proguardFile file('proguard-project.txt')
        proguardFile getDefaultProguardFile('proguard-android-optimize.txt')
    }
}

Alternatively you can include dependecy to jsr305.jar in build.gradle dependencies:

compile 'com.google.code.findbugs:jsr305:2.0.2'

...with only -dontwarn sun.misc.Unsafe in ProGuard config, but I preferred using -dontwarn also for the javax stuff.

I had to add the following lines to my proguard rules file when upgrading from 23.4-android to 23.5-android:

-dontwarn afu.org.checkerframework.**
-dontwarn org.checkerframework.**

The proguard warnings that I saw from the update (before adding new rules) are listed below for reference:

Warning: afu.org.checkerframework.checker.experimental.tainting_qual.qual.Untainted: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.experimental.tainting_qual.qual.Untainted: can't find referenced class afu.com.sun.source.tree.Tree
Warning: afu.org.checkerframework.checker.experimental.tainting_qual.qual.Untainted: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.experimental.tainting_qual.qual.Untainted: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.fenum.qual.FenumBottom: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.fenum.qual.FenumBottom: can't find referenced class afu.com.sun.source.tree.Tree
Warning: afu.org.checkerframework.checker.fenum.qual.FenumBottom: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.formatter.qual.FormatBottom: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.formatter.qual.FormatBottom: can't find referenced class afu.com.sun.source.tree.Tree
Warning: afu.org.checkerframework.checker.formatter.qual.FormatBottom: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.guieffect.qual.AlwaysSafe: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.guieffect.qual.AlwaysSafe: can't find referenced class afu.com.sun.source.tree.Tree
Warning: afu.org.checkerframework.checker.guieffect.qual.AlwaysSafe: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.i18n.qual.Localized: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.i18n.qual.Localized: can't find referenced class afu.com.sun.source.tree.Tree
Warning: afu.org.checkerframework.checker.i18n.qual.Localized: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.i18n.qual.Localized: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.i18n.qual.Localized: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.i18n.qual.Localized: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.i18n.qual.Localized: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.i18n.qual.Localized: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.i18nformatter.qual.I18nFormatBottom: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.i18nformatter.qual.I18nFormatBottom: can't find referenced class afu.com.sun.source.tree.Tree
Warning: afu.org.checkerframework.checker.i18nformatter.qual.I18nFormatBottom: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.initialization.qual.FBCBottom: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.initialization.qual.FBCBottom: can't find referenced class afu.com.sun.source.tree.Tree
Warning: afu.org.checkerframework.checker.initialization.qual.FBCBottom: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.interning.qual.Interned: can't find referenced class afu.org.checkerframework.framework.type.AnnotatedTypeMirror$AnnotatedPrimitiveType
Warning: afu.org.checkerframework.checker.interning.qual.Interned: can't find referenced class afu.org.checkerframework.framework.type.AnnotatedTypeMirror
Warning: afu.org.checkerframework.checker.interning.qual.Interned: can't find referenced class afu.com.sun.source.tree.LiteralTree
Warning: afu.org.checkerframework.checker.interning.qual.Interned: can't find referenced class afu.org.checkerframework.framework.type.AnnotatedTypeMirror$AnnotatedPrimitiveType
Warning: afu.org.checkerframework.checker.nullness.qual.KeyForBottom: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.nullness.qual.KeyForBottom: can't find referenced class afu.com.sun.source.tree.Tree
Warning: afu.org.checkerframework.checker.nullness.qual.KeyForBottom: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.nullness.qual.NonNull: can't find referenced class afu.org.checkerframework.framework.type.AnnotatedTypeMirror$AnnotatedPrimitiveType
Warning: afu.org.checkerframework.checker.nullness.qual.NonNull: can't find referenced class afu.org.checkerframework.framework.type.AnnotatedTypeMirror
Warning: afu.org.checkerframework.checker.nullness.qual.NonNull: can't find referenced class afu.org.checkerframework.framework.type.AnnotatedTypeMirror$AnnotatedNoType
Warning: afu.org.checkerframework.checker.nullness.qual.NonNull: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.nullness.qual.NonNull: can't find referenced class afu.com.sun.source.tree.Tree
Warning: afu.org.checkerframework.checker.nullness.qual.NonNull: can't find referenced class javax.lang.model.type.TypeKind
Warning: afu.org.checkerframework.checker.nullness.qual.NonNull: can't find referenced class afu.org.checkerframework.framework.type.AnnotatedTypeMirror$AnnotatedPrimitiveType
Warning: afu.org.checkerframework.checker.nullness.qual.NonNull: can't find referenced class afu.org.checkerframework.framework.type.AnnotatedTypeMirror$AnnotatedNoType
Warning: afu.org.checkerframework.checker.nullness.qual.NonNull: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.nullness.qual.NonNull: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.nullness.qual.NonNull: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.nullness.qual.NonNull: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.nullness.qual.NonNull: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.nullness.qual.NonNull: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.nullness.qual.NonNull: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.nullness.qual.NonNull: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.nullness.qual.NonNull: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.nullness.qual.NonNull: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.nullness.qual.Nullable: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.nullness.qual.Nullable: can't find referenced class afu.com.sun.source.tree.Tree
Warning: afu.org.checkerframework.checker.nullness.qual.Nullable: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.oigj.qual.Mutable: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.oigj.qual.Mutable: can't find referenced class afu.com.sun.source.tree.Tree
Warning: afu.org.checkerframework.checker.oigj.qual.Mutable: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.oigj.qual.Mutable: can't find referenced class javax.lang.model.type.TypeKind
Warning: afu.org.checkerframework.checker.oigj.qual.OIGJMutabilityBottom: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.oigj.qual.OIGJMutabilityBottom: can't find referenced class afu.com.sun.source.tree.Tree
Warning: afu.org.checkerframework.checker.oigj.qual.OIGJMutabilityBottom: can't find referenced class afu.org.checkerframework.framework.type.AnnotatedTypeMirror$AnnotatedPrimitiveType
Warning: afu.org.checkerframework.checker.oigj.qual.OIGJMutabilityBottom: can't find referenced class afu.org.checkerframework.framework.type.AnnotatedTypeMirror
Warning: afu.org.checkerframework.checker.oigj.qual.OIGJMutabilityBottom: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.oigj.qual.OIGJMutabilityBottom: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.oigj.qual.OIGJMutabilityBottom: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.oigj.qual.OIGJMutabilityBottom: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.oigj.qual.OIGJMutabilityBottom: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.oigj.qual.OIGJMutabilityBottom: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.oigj.qual.OIGJMutabilityBottom: can't find referenced class afu.org.checkerframework.framework.type.AnnotatedTypeMirror$AnnotatedPrimitiveType
Warning: afu.org.checkerframework.checker.regex.classic.qual.RegexBottom: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.regex.classic.qual.RegexBottom: can't find referenced class afu.com.sun.source.tree.Tree
Warning: afu.org.checkerframework.checker.regex.classic.qual.RegexBottom: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.signature.qual.SignatureBottom: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.signature.qual.SignatureBottom: can't find referenced class afu.com.sun.source.tree.Tree
Warning: afu.org.checkerframework.checker.signature.qual.SignatureBottom: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.tainting.classic.qual.Untainted: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.tainting.classic.qual.Untainted: can't find referenced class afu.com.sun.source.tree.Tree
Warning: afu.org.checkerframework.checker.tainting.classic.qual.Untainted: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.tainting.classic.qual.Untainted: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.checker.units.qual.UnitsRelations: can't find referenced class afu.org.checkerframework.checker.units.UnitsRelations
Warning: afu.org.checkerframework.common.aliasing.qual.MaybeAliased: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.common.aliasing.qual.MaybeAliased: can't find referenced class afu.com.sun.source.tree.Tree
Warning: afu.org.checkerframework.common.aliasing.qual.MaybeAliased: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.common.reflection.qual.ClassValBottom: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.common.reflection.qual.ClassValBottom: can't find referenced class afu.com.sun.source.tree.Tree
Warning: afu.org.checkerframework.common.reflection.qual.ClassValBottom: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.common.reflection.qual.MethodValBottom: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.common.reflection.qual.MethodValBottom: can't find referenced class afu.com.sun.source.tree.Tree
Warning: afu.org.checkerframework.common.reflection.qual.MethodValBottom: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.common.value.qual.BottomVal: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.common.value.qual.BottomVal: can't find referenced class afu.com.sun.source.tree.Tree
Warning: afu.org.checkerframework.common.value.qual.BottomVal: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.framework.qual.ImplicitFor: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.framework.qual.ImplicitFor: can't find referenced class afu.com.sun.source.tree.Tree
Warning: afu.org.checkerframework.framework.qual.ImplicitFor: can't find referenced class afu.com.sun.source.tree.Tree$Kind
Warning: afu.org.checkerframework.framework.qual.ImplicitFor: can't find referenced class afu.com.sun.source.tree.Tree
Warning: afu.org.checkerframework.framework.qual.ImplicitFor: can't find referenced class javax.lang.model.type.TypeKind
Warning: afu.org.checkerframework.framework.qual.ImplicitFor: can't find referenced class afu.org.checkerframework.framework.type.AnnotatedTypeMirror
Warning: org.checkerframework.checker.interning.qual.Interned: can't find referenced class javax.lang.model.type.TypeKind
Warning: org.checkerframework.checker.interning.qual.Interned: can't find referenced class javax.lang.model.type.TypeKind
Warning: org.checkerframework.checker.interning.qual.Interned: can't find referenced class javax.lang.model.type.TypeKind
Warning: org.checkerframework.checker.interning.qual.Interned: can't find referenced class javax.lang.model.type.TypeKind
Warning: org.checkerframework.checker.interning.qual.Interned: can't find referenced class javax.lang.model.type.TypeKind
Warning: org.checkerframework.checker.interning.qual.Interned: can't find referenced class javax.lang.model.type.TypeKind
Warning: org.checkerframework.checker.interning.qual.Interned: can't find referenced class javax.lang.model.type.TypeKind
Warning: org.checkerframework.checker.interning.qual.Interned: can't find referenced class javax.lang.model.type.TypeKind
Warning: org.checkerframework.checker.lock.qual.GuardedBy: can't find referenced class javax.lang.model.type.TypeKind
Warning: org.checkerframework.checker.lock.qual.GuardedBy: can't find referenced class javax.lang.model.type.TypeKind
Warning: org.checkerframework.checker.lock.qual.GuardedBy: can't find referenced class javax.lang.model.type.TypeKind
Warning: org.checkerframework.checker.lock.qual.GuardedBy: can't find referenced class javax.lang.model.type.TypeKind
Warning: org.checkerframework.checker.lock.qual.GuardedBy: can't find referenced class javax.lang.model.type.TypeKind
Warning: org.checkerframework.checker.lock.qual.GuardedBy: can't find referenced class javax.lang.model.type.TypeKind
Warning: org.checkerframework.checker.lock.qual.GuardedBy: can't find referenced class javax.lang.model.type.TypeKind
Warning: org.checkerframework.checker.lock.qual.GuardedBy: can't find referenced class javax.lang.model.type.TypeKind
Warning: org.checkerframework.checker.nullness.qual.NonNull: can't find referenced class javax.lang.model.type.TypeKind
Warning: org.checkerframework.checker.nullness.qual.NonNull: can't find referenced class javax.lang.model.type.TypeKind
Warning: org.checkerframework.checker.nullness.qual.NonNull: can't find referenced class javax.lang.model.type.TypeKind
Warning: org.checkerframework.checker.nullness.qual.NonNull: can't find referenced class javax.lang.model.type.TypeKind
Warning: org.checkerframework.checker.nullness.qual.NonNull: can't find referenced class javax.lang.model.type.TypeKind
Warning: org.checkerframework.checker.nullness.qual.NonNull: can't find referenced class javax.lang.model.type.TypeKind
Warning: org.checkerframework.checker.nullness.qual.NonNull: can't find referenced class javax.lang.model.type.TypeKind
Warning: org.checkerframework.checker.nullness.qual.NonNull: can't find referenced class javax.lang.model.type.TypeKind
Warning: org.checkerframework.checker.nullness.qual.NonNull: can't find referenced class javax.lang.model.type.TypeKind
Warning: org.checkerframework.checker.units.qual.UnitsRelations: can't find referenced class org.checkerframework.checker.units.UnitsRelations
Warning: org.checkerframework.framework.qual.ImplicitFor: can't find referenced class javax.lang.model.type.TypeKind

For those interested, the full ruleset I have for guava currently is:

# Guava (official)
## Not yet defined: follow https://github.com/google/guava/issues/2117
# Guava (unofficial)
## https://github.com/google/guava/issues/2926#issuecomment-325455128
## https://stackoverflow.com/questions/9120338/proguard-configuration-for-guava-with-obfuscation-and-optimization
-dontwarn com.google.common.base.**
-dontwarn com.google.errorprone.annotations.**
-dontwarn com.google.j2objc.annotations.**
-dontwarn java.lang.ClassValue
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
# Added for guava 23.5-android
-dontwarn afu.org.checkerframework.**
-dontwarn org.checkerframework.**

One of the engineers who built R8 (Stephan Herhut) listed the following rules for the latest Guava (25.0-android) in this session from Google I/O 2018:

-dontwarn afu.org.checkerframework.**
-dontwarn org.checkerframework.**
-dontwarn com.google.errorprone.**
-dontwarn sun.misc.Unsafe
-dontwarn java.lang.ClassValue

The video also includes a short explanation of the rules (first 3 are static analysis annotation frameworks, last 2 are unavailable classes on Android which are protected by runtime checks in Guava).

I spoke with Stephan after the session and he said these will hopefully be included in the Guava documentation in the future or better yet in the consumerProguardFiles of future Guava releases. Here's hoping!

Now that Guava 19.0 is released, I found that I had to add these rules.

-keep class com.google.j2objc.annotations.** { *; }
-dontwarn   com.google.j2objc.annotations.**
-keep class java.lang.ClassValue { *; }
-dontwarn   java.lang.ClassValue
-keep class org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement { *; }
-dontwarn   org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement

For Guava 20.0 you need to add also:

# Guava 20.0
-dontwarn com.google.errorprone.annotations.CanIgnoreReturnValue
-dontwarn com.google.errorprone.annotations.concurrent.LazyInit
-dontwarn com.google.errorprone.annotations.ForOverride

This message suggests the following workaround:

-dontwarn com.google.common.collect.MinMaxPriorityQueue 

I'd like to think that Proguard could be changed to make this unnecessary, but we haven't checked with its owners.

Total proguard rule for guava 20.0. For now the latest guava 21 does not support android.

-dontwarn com.google.common.base.**
-keep class com.google.common.base.** {*;}
-dontwarn com.google.errorprone.annotations.**
-keep class com.google.errorprone.annotations.** {*;}
-dontwarn   com.google.j2objc.annotations.**
-keep class com.google.j2objc.annotations.** { *; }
-dontwarn   java.lang.ClassValue
-keep class java.lang.ClassValue { *; }
-dontwarn   org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
-keep class org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement { *; }

I just want to share what is actually working now for my app with the following in build.gradle:

compile 'com.google.guava:guava:23.5-android'

The following is in proguard-project.txt to deal with Guava. It is essentially the combination of TimTron's answer and develper_7's tip:

-dontwarn sun.misc.Unsafe
-dontwarn com.google.common.collect.MinMaxPriorityQueue
-dontwarn com.google.common.util.concurrent.FuturesGetChecked**
-dontwarn javax.lang.model.element.Modifier
-dontwarn afu.org.checkerframework.**
-dontwarn org.checkerframework.**

guava's jar files were produced by a java compiler that (unlike javac) kept extra references to private inlined constants in the constant pool of referencing classes in the same source file, which fails only with proguard 4.7, which appears to optimize away the private constant definitions, without optimizing away the references. Future guava jar files will not have such constant pool references, but there's probably a bug in proguard 4.7 that does not manifest with jar files produced by standard javac.

These proguard-rules worked for me: guava 23.3-android

-dontwarn sun.misc.Unsafe
-dontwarn com.google.common.collect.MinMaxPriorityQueue
-dontwarn com.google.common.util.concurrent.FuturesGetChecked**
-dontwarn javax.lang.model.element.Modifier
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!