Steps to reproduce:
1. Prepare a jar file containing a JDK9+ module
2. Obfuscate it with Proguard 6.0.2
3. Verify that the output jar is missing the "module-info.class" file that the original file contained
Details:
I'm upgrading a Java desktop application to JDK10 and need to leverage modules to use the javapackager to build a native package.
Everything is 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.
Shouldn't Proguard be copying the "module-info.class" file to the output jar?
module-info.class is a valid class file, but it is not used by any other class, so ProGuard removes it by default. Explicitly keeping it as an entry point should solve that:
I had tried that before but ran into an issue:
Execution failed for task ':obfuscate'.
Not sure how to get additional debugging data. I'm running proguard through gradle
Ran it through the command line and got more data:
....
Ignoring unused library classes...
Original number of library classes: 15178
Final number of library classes: 727
Inlining subroutines...
Shrinking...
java.lang.NullPointerException
at proguard.classfile.ProgramClass.constantPoolEntryAccept(ProgramClass.java:537)
at proguard.shrink.UsageMarker.markConstant(UsageMarker.java:1246)
at proguard.shrink.UsageMarker.visitRequiresInfo(UsageMarker.java:1040)
at proguard.classfile.attribute.module.ModuleAttribute.requiresAccept(ModuleAttribute.java:138)
at proguard.shrink.UsageMarker.visitModuleAttribute(UsageMarker.java:739)
at proguard.classfile.attribute.module.ModuleAttribute.accept(ModuleAttribute.java:99)
at proguard.classfile.ProgramClass.attributesAccept(ProgramClass.java:619)
at proguard.shrink.UsageMarker.markProgramClassBody(UsageMarker.java:124)
at proguard.shrink.UsageMarker.visitProgramClass(UsageMarker.java:94)
at proguard.classfile.visitor.MultiClassVisitor.visitProgramClass(MultiClassVisitor.java:67)
at proguard.classfile.ProgramClass.accept(ProgramClass.java:430)
at proguard.classfile.ClassPool.classAccept(ClassPool.java:157)
at proguard.classfile.visitor.NamedClassVisitor.visitClassPool(NamedClassVisitor.java:47)
at proguard.classfile.visitor.MultiClassPoolVisitor.visitClassPool(MultiClassPoolVisitor.java:85)
at proguard.classfile.ClassPool.accept(ClassPool.java:110)
at proguard.shrink.Shrinker.execute(Shrinker.java:90)
at proguard.ProGuard.shrink(ProGuard.java:380)
at proguard.ProGuard.execute(ProGuard.java:145)
at proguard.ProGuard.main(ProGuard.java:572)
I can't reproduce the issue yet; keeping the module-info class works for me. For the obfuscation step (which comes after the shrinking step that crashes for you), I also need to keep some attributes inside this class:
Can you post or mail your module-info.java and compiled module-info.class?
Hi,
Thanks for looking into it. I can share my module-info.java file:
I tried reproducing the issue with a new blank project so that I could share but it worked fine with that simple project and your tip to add
-keep class module-info
I'm trying to see if I can isolate the issue to any specific dependency/class file
Thanks again
I encountered the same crash. I filed a separate ticket, [#712], to track it, since this ticket is about ProGuard omitting
module-info.class
from the output JAR, which is a different issue.Related
Bugs:
#712Adding -keep class module-info to my project causes "Error: null" to be printed and the job to fail. I don't get a stack trace though but I assume this is the same issue. I'm on proguard 6.0.3
Last edit: Ashton Holmes 2018-06-23
module-info classes have to be explicitly kept. With ProGuard 6.0.3 there was an issue as it was not able to properly process such classes as they contain new constants.
This has been fixed in issue 712, ProGuard 6.2.0 should work fine.