proguard icon indicating copy to clipboard operation
proguard copied to clipboard

-addconfigurationdebugging throws NPE

Open credmond opened this issue 1 year ago • 3 comments

Proguard 7.6.1

Adding -addconfigurationdebugging, throws this NPE:

java.lang.NullPointerException: Cannot invoke "String.replace(char, char)" because "internalClassName" is null at proguard.classfile.util.ClassUtil.externalClassName(ClassUtil.java:282) ~[proguard.jar:7.6.1] at proguard.io.ClassMapDataEntryReplacer.writeClassMap(ClassMapDataEntryReplacer.java:109) ~[proguard.jar:7.6.1] at proguard.io.ClassMapDataEntryReplacer.read(ClassMapDataEntryReplacer.java:75) ~[proguard.jar:7.6.1] at proguard.io.FilteredDataEntryReader.read(FilteredDataEntryReader.java:71) ~[proguard.jar:7.6.1] at proguard.io.FilteredDataEntryReader.read(FilteredDataEntryReader.java:71) ~[proguard.jar:7.6.1] at proguard.io.ExtraDataEntryReader.readExtraEntries(ExtraDataEntryReader.java:150) ~[proguard.jar:7.6.1] at proguard.io.ExtraDataEntryReader.read(ExtraDataEntryReader.java:123) ~[proguard.jar:7.6.1] at proguard.io.RenamedDataEntryReader.read(RenamedDataEntryReader.java:81) ~[proguard.jar:7.6.1] at proguard.io.FilteredDataEntryReader.read(FilteredDataEntryReader.java:71) ~[proguard.jar:7.6.1] at proguard.io.FilteredDataEntryReader.read(FilteredDataEntryReader.java:71) ~[proguard.jar:7.6.1] at proguard.io.JarReader.read(JarReader.java:74) ~[proguard.jar:7.6.1] at proguard.io.DirectorySource.readFiles(DirectorySource.java:55) ~[proguard.jar:7.6.1] at proguard.io.DirectorySource.pumpDataEntries(DirectorySource.java:44) ~[proguard.jar:7.6.1] at proguard.InputReader.readInput(InputReader.java:278) ~[proguard.jar:7.6.1] at proguard.InputReader.readInput(InputReader.java:229) ~[proguard.jar:7.6.1] at proguard.OutputWriter.writeOutput(OutputWriter.java:392) ~[proguard.jar:7.6.1] at proguard.OutputWriter.execute(OutputWriter.java:148) ~[proguard.jar:7.6.1] at proguard.pass.PassRunner.run(PassRunner.java:24) ~[proguard.jar:7.6.1] at proguard.ProGuard.writeOutput(ProGuard.java:586) ~[proguard.jar:7.6.1] at proguard.ProGuard.execute(ProGuard.java:252) ~[proguard.jar:7.6.1] at proguard.ProGuard.main(ProGuard.java:642) [proguard.jar:7.6.1]

credmond avatar Dec 13 '24 23:12 credmond

Same error with the 7.5.0 version.

ptitjes avatar Dec 18 '24 08:12 ptitjes

This looks like the same issue as #224: the exception comes from the line here where the super class name of a class is null.

It's quite likely due to Java modules. In projects using Java modules, there are classes files called module-info.class. These classes do not have a superclass name like normal class files e.g.

$ javap -c -v -p -cp mod1.jar module-info
Classfile jrt:/jdk.zipfs/module-info.class
  Last modified 6 Aug 2021; size 325 bytes
  SHA-256 checksum c7b7308ed3e2e734899d18aa45d4e491e4700f51cb601d36749d70efafac37f5
  Compiled from "module-info.java"
module jdk.zipfs@17
  minor version: 0
  major version: 61
  flags: (0x8000) ACC_MODULE
  this_class: #2                          // "module-info"
  super_class: #0
  interfaces: 0, fields: 0, methods: 0, attributes: 4
Constant pool:
   #1 = Utf8               module-info
...

This can be easily reproduced on a sample like this one.

$ bin/proguard.sh -injars mod1.jar -addconfigurationdebugging -outjars out.jar -ignorewarnings -keep class \*
ProGuard, version 7.6.0
....
Warning: -addconfigurationdebugging is enabled; the resulting build will contain obfuscation information.
It should only be used for debugging purposes.
Unexpected error
java.lang.NullPointerException: Cannot invoke "String.replace(char, char)" because "internalClassName" is null
	at proguard.classfile.util.ClassUtil.externalClassName(ClassUtil.java:271) ~[proguard.jar:7.6.0]
	at proguard.io.ClassMapDataEntryReplacer.writeClassMap(ClassMapDataEntryReplacer.java:109) ~[proguard.jar:7.6.0]
	at proguard.io.ClassMapDataEntryReplacer.read(ClassMapDataEntryReplacer.java:75) ~[proguard.jar:7.6.0]
...

You could try using a filter to filter out the module-info files from the input during the addconfiguration build, like:

-injars my.jar(!module-info.class)

Related to modules, they are not fully supported by ProGuard - see #455, #122.

mrjameshamilton avatar Dec 19 '24 15:12 mrjameshamilton

Thanks. Yeah, I actually made my JAR non-modular (removing modular-info.class altogether) because Proguard couldn't support it as per your other bug links, and I noticed this NPE went away.

Any idea why Proguard won't handle module-info.class after all these years? Seems to me like it should be fairly simple (maybe it isn't). It's not a standard class but it is just byte-code.

credmond avatar Dec 19 '24 18:12 credmond