6

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:

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.**
OneWorld
  • 17,512
  • 21
  • 86
  • 136

2 Answers2

6

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

OneWorld
  • 17,512
  • 21
  • 86
  • 136
  • The trailing `,**` could be `,*` instead ... the single asterisk is interpreted as any class regardless of package, apparently for backward compatibility. – neuralmer Feb 25 '20 at 15:37
  • What should I write in my proguard rules? I wrote -keep class !com.lol.loll.lolllll.appl.MainActivity.** but it doesn't work! I receive tons of warnings! – Curio Oct 29 '20 at 09:13
  • Did you note the 1st sentence of my answer? Your example lacks `,**` at the end. You probably should ask your own question to your specific problem. – OneWorld Oct 29 '20 at 09:38
  • I'm a bit unclear why `,**` changes behavior, so I asked another question about it https://stackoverflow.com/questions/67506193/what-does-the-change-behavior-for-r8-vs-proguard – ZakTaccardi May 12 '21 at 15:02
5

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.**,**
Evin1_
  • 12,292
  • 9
  • 45
  • 47
T. Neidhart
  • 6,060
  • 2
  • 15
  • 38
  • So, my syntax is correct?: `-keep class !org.apache.**` – OneWorld Dec 11 '19 at 10:38
  • Yes thats correct, I had a small typo its android.enableR8=false – T. Neidhart Dec 11 '19 at 11:56
  • With your correction (`android.enableR8=false`) I managed to turn off R8. However, then proguard wouldn't finish due to lots of warnings. So, I added `-dontwarn` which finally built an APK. My negated rules were also not recognized with that approach. – OneWorld Dec 11 '19 at 12:52
  • I am pretty sure they were. As you wrote, there will be additional keep rules automatically added by the Android gradle plugin. All keep rules are treated independently. So if there are other keep rules that keep certain classes this keep rules will be honored and the specified classes will be kept. – T. Neidhart Dec 11 '19 at 14:43
  • Are you saying the negator only works if I have one keep rule (the one with the negator)? – OneWorld Dec 11 '19 at 16:07
  • Yes, every keep rule is treated independently. – T. Neidhart Dec 11 '19 at 17:24
  • So, all those questions I listed above, won't work anymore since Android Studio adds numerous `-keep` rules itself? I wonder why nobody raised that question before. What about the last approach I described (`-dontshrink -dontoptimize -dontobfuscate -keep,allowshrinking,allowoptimization,allowobfuscation class org.apache.**`). Why is that not working either? Instead it keeps everything, even the apache packages. – OneWorld Dec 12 '19 at 08:13
  • I dont know what goes wrong in your case, but the keep rule should be honored and it works in my tests. When using -dontobfuscate nothing will be obfuscated, so all classes will be kept as expected. – T. Neidhart Dec 12 '19 at 09:14
  • I tested it again, with ProGuard it works correctly, R8 does not seem to take the negated rule correctly into account. As already said I would raise a ticket with the R8 project or switch to ProGuard as explained. – T. Neidhart Dec 12 '19 at 09:36
  • I updated the answer with a rule that works also with R8 – T. Neidhart Dec 12 '19 at 09:39
  • What should I write in my proguard rules? I wrote -keep class !com.lol.loll.lolllll.appl.MainActivity.** but it doesn't work! I receive tons of warnings! – Curio Oct 29 '20 at 09:14