Menu

#704 Proguard not copying module-info.class file to output jar.

v6.0
closed-duplicate
None
Medium
2019-12-06
2018-05-09
No

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?

Related

Bugs: #712

Discussion

  • Eric Lafortune

    Eric Lafortune - 2018-05-09

    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:

    -keep class module-info
    
     
  • Leandro Barbosa

    Leandro Barbosa - 2018-05-10

    I had tried that before but ran into an issue:

    • What went wrong:
      Execution failed for task ':obfuscate'.

      java.lang.NullPointerException (no error message)

    Not sure how to get additional debugging data. I'm running proguard through gradle

     
  • Leandro Barbosa

    Leandro Barbosa - 2018-05-10

    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)

    Hope this helps!
    
     
  • Eric Lafortune

    Eric Lafortune - 2018-05-10

    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:

    -keepattributes Module*
    

    Can you post or mail your module-info.java and compiled module-info.class?

     
  • Eric Lafortune

    Eric Lafortune - 2018-05-10
    • status: open --> open-works-for-me
     
  • Leandro Barbosa

    Leandro Barbosa - 2018-05-12

    Hi,

    Thanks for looking into it. I can share my module-info.java file:

    module myapp {
        requires java.desktop;
        requires java.prefs;
        requires forms; //jar dependency
        requires java.scripting;
        requires org.apache.commons.lang3;  //jar dependency
        requires rhino; //jar dependency
        requires jdk.incubator.httpclient;
    }
    

    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

     
  • Richard Alderson

    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: #712

  • Ashton Holmes

    Ashton Holmes - 2018-06-23

    Adding -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
  • T. Neidhart

    T. Neidhart - 2019-12-06
    • status: open-works-for-me --> closed-duplicate
     
  • T. Neidhart

    T. Neidhart - 2019-12-06

    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.

     

Log in to post a comment.