JDK-8062335 : Pack200 Java implementation differs from C version, outputs unused UTF8 for BootstrapMethods
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util.jar
  • Priority: P4
  • Status: Resolved
  • Resolution: Duplicate
  • Submitted: 2014-10-28
  • Updated: 2016-09-02
  • Resolved: 2016-09-02
Related Reports
Duplicate :  
Relates :  
Description
The Pack200 spec is designed to specify the bitwise image of uncompressed files.
So both implementations of the unpacker (C and Java) should produce the same output.
A disagreement signals a bug in one or both implementations.

Jeroen Fritjers reports:  It appears that under some (difficult to isolate so far) circumstances, the "BootstrapMethods" UTF8 CP entry ends up in the class, even though there aren't any bootstrap methods.

Jeroen also says that moving the statement in PackageReader.java that begins "if (bsms.isEmpty())" before the statement "int changed = cls.expandLocalICs();" seems to fix the problem.

The correctness of constant pool pruning depends sensitively on the ordering of other stripping operations.  It also interacts with the pruning of BootstrapMethods and InnerClasses attributes (which are also global tables for Pack200). It may be that a more iterative code pattern is required in PackageReader.reconstructLocalCPMap, which would prune the class file's symbolic references until nothing changes.  On the other hand, it may be enough to find the most correct static ordering of pruning operations, as in Jeroen's suggested fix.
Comments
Will be fixed with JDK-8151901
02-09-2016

Can be reproduced by packing the compilation of this file and its package siblings: https://code.google.com/p/guava-libraries/source/browse/guava/src/com/google/common/reflect/MutableTypeToInstanceMap.java The native unpacker correctly removes the Utf8 constant "BootstrapMethods" from the CP, while the Java unpacker does not. Note that in no case does the affected class file contain an actual BootstrapMethod attribute. This is only about the lingering string constant for an attribute that is not present. Script for reproducing the bug (given the packed form of the Guava classes): # create 8062335-test.pack unpack200 8062335-test.{pack,native.jar} # note: pack200 -r (repacking) is the simplest way to access the non-native unpacker pack200 -J-Dcom.sun.java.util.jar.pack.disable.native=true -r 8062335-test.{repack1,native}.jar pack200 -r 8062335-test.{repack0,native}.jar rm -rf 8062335-test.*.dir (for f in 8062335-test.*.jar; do d=${f%.jar}.dir; unzip $f -d $d; done) diff -qr 8062335-test.native.dir 8062335-test.repack0.dir || echo "*** Should be same" diff -qr 8062335-test.native.dir 8062335-test.repack1.dir || echo "*** Different, so there is a bug" (for x in 8062335-test.{native,repack1}; do javap > $x.javap -p -c -v $x.dir/com/google/common/reflect/'Types$GenericArrayTypeImpl'.class; done) diff -U1 8062335-test.*.javap > 8062335-test.diff # bug in the non-native unpacker shows up as a flaw in repack1.dir grep BootstrapMethods 8062335-test.diff
29-10-2014