7

I'm currently using an Android library that uses a lot of reflection.

As soon as I enable proguard, and run it... it crashes.

Why? It uses a lot of reflection and the methods are only invoked via reflection, so they are detected by proguard as unused and removed during the shrinking process, so a a NoSuchMethodError is thrown.

Why this happens? That is easy to figure out they are removed during the shrinking process as proguard considers they are unused and therefore removes that pieces of code (all the methods)

So, how can I configure proguard to avoid shrinking or obfuscating an entire package? (the library)

Note: I don't want to use the -dontshrink option, as it's all or nothing and I just want to avoid a specific package.


More info:

The runtime error is the following:

E/AndroidRuntime: FATAL EXCEPTION: main Process: com.my.app.debug, PID: 3771 
java.lang.NoSuchMethodError: observeValueForKeyPath [class java.lang.String, class java.lang.Object, class com.my.lib.util.Dictionary, class java.lang.Object]
at com.my.lib.util.Observable$ObservationManager$Observer.<init>(SourceFile:47)
at com.my.lib.util.Observable$ObservationManager$Observer.<init>(SourceFile:26)
at com.my.lib.util.Observable$ObservationManager.addObserver(SourceFile:159)
...

Take note that the problem is one an inner inner class...

My current configuration has something like:

-keep,includedescriptorclasses class com.my.** { *; }
-keepclassmembers class com.my.lib** { *; }
-keep,includedescriptorclasses class com.my.lib.util.Observable$* { *; }
-keep,includedescriptorclasses class com.my.lib.util.Observable$*$* { *; }

But this apparently only avoids obfuscating the methods not removed during the shrinking process... I need to avoid removing methods during shrinking.

neteinstein
  • 17,529
  • 11
  • 93
  • 123
  • Possible duplicate of [How to keep/exclude a particular package path when using proguard?](http://stackoverflow.com/questions/4830474/how-to-keep-exclude-a-particular-package-path-when-using-proguard) – Elltz Apr 01 '16 at 18:52
  • It's not a duplicate. I'm specifically searching for a way to disable shrinking that the other answer doesn't solve (and obfuscation which the other answer indeed answers). – neteinstein Apr 01 '16 at 21:21
  • Why is the global -dontshrink so terrible. Do you **need** your app shrunk. Is the shrinking worth the pain it's currently causing you? – Richard Tingle Apr 03 '16 at 21:29
  • Why should I stop shrinking my app just because a lib uses reflection? I can, but that's just the easy way. – neteinstein Apr 03 '16 at 21:33

4 Answers4

3

According to the documentation -keep should work even when shrinking, while -keepclassmembers only works "if [the] classes are preserved as well".

F43nd1r
  • 7,690
  • 3
  • 24
  • 62
0
-keep class com.library.** { *; } 
gaara87
  • 2,087
  • 3
  • 21
  • 43
0

For the sake of people in the future with similar problems, I'll explain what really was happening:

  1. The -keep class my.app.package was really avoiding methods to be removed by shrinking and obfuscated (@F43nd1r's answer made me realize that by really pointing that the docs said that it avoid also shrinking), so the problem was elsewhere

  2. After decompiling the lib's code and passing some time reading it, I found that it received as a parameter an instance of another class (not from that lib) and a string with a method name that it used for reflection. That was the problem, I needed to also avoid obfuscating that class.

neteinstein
  • 17,529
  • 11
  • 93
  • 123
0

I use the option -dontshrink to prevent shrinking. Source: link

YetAnotherBot
  • 1,937
  • 2
  • 25
  • 32