Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent proguard from removing "module-info.class" from the output jar?

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?

like image 244
lbarbosa Avatar asked May 06 '18 18:05

lbarbosa


People also ask

How do you keep a class in ProGuard?

-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.

How does ProGuard obfuscation work?

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.

How do you set ProGuard rules?

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.


1 Answers

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.

like image 197
lbarbosa Avatar answered Sep 20 '22 13:09

lbarbosa