Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proguard (R8) negate operator not working to keep anything except certain packages

The negator (exclamation mark) in proguard should allow me to keep anthing but the apache libraries:

-keep class !org.apache.**

According to those answers. That's the way to go:

  • How to negate classname with Proguard
  • Enable Proguard for only two packages in large Android application
  • Android proguard Ignore All Classes except of one
  • Proguard Android do not obfuscate anything except few classes
  • Proguard: How to keep everything except specific condition?
  • Can we shrink all classes but only obfuscate some with proguard?

However, it obfuscates all classes in my APK.

That's part of my build.gradle (I have Android Studio 3.5.3)

compileSdkVersion 29
buildToolsVersion "29.0.2"
//...
buildTypes {

    release {

        minifyEnabled true
        proguardFiles /*getDefaultProguardFile('proguard-android.txt'),*/  'proguard-rules.pro'

        // Enables resource shrinking, which is performed by the
        // Android Gradle plugin.
        shrinkResources false
    }
}

dependencies {
    //Utility libs
    implementation 'org.apache.commons:commons-collections4:4.1'
    implementation 'org.apache.commons:commons-lang3:3.4'
    implementation group: 'commons-io', name: 'commons-io', version: '2.5'
}

After I added -printconfiguration to my proguard-rules.pro file I saw there are numerous -keep rules following my -keep class !org.apache.**

-printconfiguration
-keep class !org.apache.**

# Referenced at ***anonymized***\app\build\intermediates\merged_manifests\release\AndroidManifest.xml:180
-keep class android.support.v4.app.CoreComponentFactory { <init>(); }
# Referenced at ***anonymized***\app\build\intermediates\merged_manifests\release\AndroidManifest.xml:180
-keep class com.mycompany.MyApplication { <init>(); }
# Referenced at C:\Users\***anonymized***\.gradle\caches\transforms-2\files-2.1\7f5f0b3369d8fa8a72a20e2278ec0acc\appcompat-v7-28.0.0\res\layout\abc_action_menu_item_layout.xml:17
-keep class android.support.v7.view.menu.ActionMenuItemView { <init>(...); }

That approach suggested by Ezekiel Baniaga also didn't work. Instead it keeps everything including the apache packages:

proguard-rules.pro

-printconfiguration

-dontshrink

-dontoptimize

-dontobfuscate

-keep,allowshrinking,allowoptimization,allowobfuscation class org.apache.**
like image 909
OneWorld Avatar asked Dec 09 '19 12:12

OneWorld


2 Answers

You should file a bug report with the R8 project if this does not work anymore.

In order to keep using Proguard in the meantime, you can add this to your gradle.properties files:

android.enableR8=false

Further tests show that the implicit behavior of ProGuard is not implemented like that in R8.

So a rule like:

-keep class !org.apache.**

will implicitly keep all other classes when using ProGuard, but not when using R8. To achieve the same behavior with R8, change the rule to this:

-keep class !org.apache.**,**
like image 92
T. Neidhart Avatar answered Nov 14 '22 22:11

T. Neidhart


I had to add ,** to get it working. Thanks T. Neidhart!

-keep class !org.apache.**,**

The previous example preserved class names but still obfuscated members. So I had to add { *; }:

-keep class !org.apache.**,** { *; }

That's how I obfuscate multiple packages (I have to use them all in one keep rule!)

-keep class !org.apache.**, !org.zeroturnaround.**, !com.drew.**, ** { *; }

To find out what my problem is with -dontshrink -dontoptimize -dontobfuscate -keep,allowshrinking,allowoptimization,allowobfuscation class org.apache.** I could add -whyareyoukeeping according to https://www.guardsquare.com/en/products/proguard/manual/usage

like image 30
OneWorld Avatar answered Nov 14 '22 22:11

OneWorld