I'm upgrading a Java desktop application to JDK10 and need to leverage modules to use the javapackager
to build a native package.
Everything was working great until I added an obfuscation step using Proguard (6.0.2).
Once I enabled obfuscation (using a working proguard configuration file from the < JDK9 project) it works as expected but Proguard removes the module-info.class
from the output JAR which prevents javapackager
from finding the module.
According to Proguard's documentation for the injars
parameter
By default, any non-class files will be copied without changes.
The problem here is that module-info.class
is a "class" file (albeit a weird one). The "keep" rules depend on class names so I don't think there is any rule I can use to prevent this removal.
How can I get Proguard to keep the module-info.class
file?
-keepclassmembernames. This is the most permissive keep directive; it lets ProGuard do almost all of its work. Unused classes are removed, the remaining classes are renamed, unused members of those classes are removed, but then the remaining members keep their original names.
In the obfuscation step, ProGuard renames classes and class members that are not entry points. In this entire process, keeping the entry points ensures that they can still be accessed by their original names. The preverification step is the only step that doesn't have to know the entry points.
When you create a new project or module using Android Studio, the IDE creates a <module-dir>/proguard-rules.pro file for you to include your own rules. You can also include additional rules from other files by adding them to the proguardFiles property in your module's build.
After filing a bug report, Proguard's author confirmed that we need to treat module-info
as just another class and add a rule to keep it, like this:
-keep class module-info
and possibly using
-keepattributes Module*
In my case, I actually had tried it before posting the question but it didn't work for me on the project I was using it with (I got a NullPointerException
when I tried it, more details in the bug report)
After the author's response, I tried it on a simpler project and the "keep" rule above worked fine so it meant that something specific to my first project was causing the issue.
I worked around the issue in that project for now by using gradle to copy the module-info.class
from the unobfuscated jar into the obfuscated one. It's not pretty but it works.
Hope this helps anyone in the same situation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With