I found that there seem to be 2 general solutions:
- don’t obfuscate what is referred to through the reflection API [Retroguard, Jobfuscate]
- replace Strings in reflection API invocations with the obfuscated name.
Those solutions work only for calls within the same project – client code (in another project) may not use the reflection API to access non-public API methods.
In the case of 2 it also only works when the Reflection API is used with Strings known at compile-time (private methods testing?). In those cases dp4j also offers a solution injecting the reflection code after obfuscation.
Reading Proguard FAQ I wondered if 2 otherwise always worked when it says:
ProGuard automatically handles
constructs like
Class.forName(“SomeClass”) and
SomeClass.class. The referenced
classes are preserved in the shrinking
phase, and the string arguments are
properly replaced in the obfuscation
phase.With variable string arguments, it’s generally not possible to determine
their possible values.
Q: what does the statement in bold mean? Any examples?
basically if you pass a non-constant string to Class.forName, there’s generally no way for proguard or any obfuscation tool to figure out what class you are talking about, and thus can’t automatically adjust the code for you.