JDK-8003549 : (pack200) assertion errors when processing lambda class files with IMethods
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util.jar
  • Affected Version: 8
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2012-11-16
  • Updated: 2013-03-22
  • Resolved: 2013-02-02
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8
8 b77Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
When running pack200 with assertion enabled assertions are fired, these
need to be investigated and fixed before GA.

% pack200 -J-Xmx1g -J-esa -J-ea -v output.jar.pack.gz rt.jar
not found: InterfaceMethodref=IMethod:java/util/streams/primitives/IntIterator.(Ljava/util/functions/Block;)V.forEach
Exception in thread "main" java.lang.AssertionError
        at com.sun.java.util.jar.pack.ConstantPool$Index.indexOf(ConstantPool.java:1102)
        at com.sun.java.util.jar.pack.BandStructure.encodeRef(BandStructure.java:1055)
        at com.sun.java.util.jar.pack.BandStructure$CPRefBand.encodeRefOrNull(BandStructure.java:1032)
        at com.sun.java.util.jar.pack.BandStructure$CPRefBand.putRef(BandStructure.java:1004)
        at com.sun.java.util.jar.pack.PackageWriter.writeByteCodes(PackageWriter.java:1620)
        at com.sun.java.util.jar.pack.PackageWriter.writeMembers(PackageWriter.java:1225)
        at com.sun.java.util.jar.pack.PackageWriter.writeClassesAndByteCodes(PackageWriter.java:1200)
        at com.sun.java.util.jar.pack.PackageWriter.write(PackageWriter.java:79)
        at com.sun.java.util.jar.pack.PackerImpl$DoPack.flushPackage(PackerImpl.java:594)
        at com.sun.java.util.jar.pack.PackerImpl$DoPack.flushAll(PackerImpl.java:548)
        at com.sun.java.util.jar.pack.PackerImpl$DoPack.run(PackerImpl.java:483)
        at com.sun.java.util.jar.pack.PackerImpl.pack(PackerImpl.java:98)
        at com.sun.java.util.jar.pack.Driver.main(Driver.java:313)

Comments
The underlying problem also arises with the java.time classes. Failure mode without assertions: ./b00/linux-i586-ea/images/j2sdk-image/bin/pack200 --repack --strip-debug rt.jar Exception in thread "main" java.io.IOException: null ref at com.sun.java.util.jar.pack.NativeUnpack.getNextFile(Native Method) at com.sun.java.util.jar.pack.NativeUnpack.run(NativeUnpack.java:211) at com.sun.java.util.jar.pack.NativeUnpack.run(NativeUnpack.java:243) at com.sun.java.util.jar.pack.UnpackerImpl.unpack(UnpackerImpl.java:135) at com.sun.java.util.jar.pack.Driver.main(Driver.java:354) Then I tried with the native code disabled: > ./b00/linux-i586-ea/images/j2sdk-image/bin/pack200 -J-Dcom.sun.java.util.jar.pack.disable.native=true --repack --strip-debug rt.jar Feb 06, 2013 8:18:06 AM com.sun.java.util.jar.pack.Utils$Pack200Logger warning WARNING: Error on output of java/time/DayOfWeek Exception in thread "main" java.lang.NullPointerException at com.sun.java.util.jar.pack.ConstantPool$Index.findIndexLocation(ConstantPool.java:1128) at com.sun.java.util.jar.pack.ConstantPool$Index.findIndexOf(ConstantPool.java:1079) at com.sun.java.util.jar.pack.ConstantPool$Index.indexOf(ConstantPool.java:1096) at com.sun.java.util.jar.pack.Fixups.finishRefs(Fixups.java:449) at com.sun.java.util.jar.pack.Code.finishRefs(Code.java:329) at com.sun.java.util.jar.pack.ClassWriter.writeCode(ClassWriter.java:279) at com.sun.java.util.jar.pack.ClassWriter.writeAttributes(ClassWriter.java:254) at com.sun.java.util.jar.pack.ClassWriter.writeMember(ClassWriter.java:206) at com.sun.java.util.jar.pack.ClassWriter.writeMembers(ClassWriter.java:197) at com.sun.java.util.jar.pack.ClassWriter.write(ClassWriter.java:98) at com.sun.java.util.jar.pack.UnpackerImpl$DoUnpack.unpackSegment(UnpackerImpl.java:247) at com.sun.java.util.jar.pack.UnpackerImpl$DoUnpack.run(UnpackerImpl.java:210) at com.sun.java.util.jar.pack.UnpackerImpl.unpack(UnpackerImpl.java:131) at com.sun.java.util.jar.pack.Driver.main(Driver.java:354)
07-02-2013

Thus we have to do things: 1. Provide an early detection system for such a case and throw a ClassFormatException, using this we can by-pass only those class files which have this scheme. 2. Provide a way for for pack200 to deal with this new scheme, one approach is to use byte code escapes invented for invokedynamic and other future expansions of the Instruction set.
25-01-2013

After much discussion it is not clear which way this should be implemented, Rose suggests: -----from email The existing design allows JVMs to put different structures in place for interface calls (compared with virtual or static calls). Interface calls tend to require more information to link than other calls, which require a simple method entry point or vtable index. Pack200 simply respects this distinction, and gets a very slight increase in compression. The index associated with in invokeinterface instruction is usually shorter (less information content) since there are fewer options compared with invokevirtual, etc. It would be just as easy for Pack (and I considered this) to collapse MRefs and IMRefs. The main reason we didn't is that the class file requires the distinction, and if they were collapsed there would have to be a side band somewhere giving the 1-bit difference. It looks like you either need to relax restrictions to (a) allow invokespecial to reference an IMRef, or else (b) allow a MRef to refer to an interface. For Pack, (b) would be easier, and (on balance) I think it would be more logical to allow a MRef to refer to a concrete method whether or not it is in an interface; then an IMRef is always the special 2-component message selector for an invokeinterface. ��� John
24-01-2013

Reproducible test case: interface Block<T>{} interface KIterator<T>{ default void forEachBlock(Block<? super T> block){} } interface IntIterator extends KIterator<Integer> { default void forEach(Block<? super Integer>sink){} } class A implements IntIterator { public void next() {}; @Override public void forEach(Block block){ // ----causes the issue------- IntIterator.super.forEach(block); } } compiling this into a jar and running with pack200 will cause the above failures. The reason is because of A.class has the following public void forEach(Block); flags: ACC_PUBLIC Code: stack=2, locals=2, args_size=2 0: aload_0 1: aload_1 2: invokespecial #2 // InterfaceMethod IntIterator.forEach:(LBlock;)V 5: return LineNumberTable: line 14: 0 line 15: 5 In the above line invokespecial is called on an InterfaceMethod this is new in JSR-335 which is not yet specified at the time of this writing, and has been communicated to the spec. owners. Therefore pack200::PackageWriter.writeByteCodes needs to use InterfaceMethod index for invokespecial byte code, based on the forthcoming specification.
06-12-2012

Adding test name to get matched in Aurora: tools/pack200/CommandLineTests.java
04-12-2012

One more issue relating to this in Pack200Test.java WARNING: Error on output of java/util/stream/primitive/IntSpinedList$SpinedListSpliterator java.lang.RuntimeException: java.lang.NullPointerException at Pack200Test.doPackUnpack(Pack200Test.java:113) at Pack200Test.main(Pack200Test.java:132) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:474) at com.sun.javatest.regtest.MainWrapper$MainThread.run(MainWrapper.java:94) at java.lang.Thread.run(Thread.java:722) Caused by: java.lang.NullPointerException at com.sun.java.util.jar.pack.ConstantPool$Index.findIndexLocation(ConstantPool.java:1128) at com.sun.java.util.jar.pack.ConstantPool$Index.findIndexOf(ConstantPool.java:1079) at com.sun.java.util.jar.pack.ConstantPool$Index.indexOf(ConstantPool.java:1096) at com.sun.java.util.jar.pack.Fixups.finishRefs(Fixups.java:449) at com.sun.java.util.jar.pack.Code.finishRefs(Code.java:329) at com.sun.java.util.jar.pack.ClassWriter.writeCode(ClassWriter.java:279) at com.sun.java.util.jar.pack.ClassWriter.writeAttributes(ClassWriter.java:254) at com.sun.java.util.jar.pack.ClassWriter.writeMember(ClassWriter.java:206) at com.sun.java.util.jar.pack.ClassWriter.writeMembers(ClassWriter.java:197) at com.sun.java.util.jar.pack.ClassWriter.write(ClassWriter.java:98) at com.sun.java.util.jar.pack.UnpackerImpl$DoUnpack.unpackSegment(UnpackerImpl.java:247) at com.sun.java.util.jar.pack.UnpackerImpl$DoUnpack.run(UnpackerImpl.java:210) at com.sun.java.util.jar.pack.UnpackerImpl.unpack(UnpackerImpl.java:131) at com.sun.java.util.jar.pack.UnpackerImpl.unpack(UnpackerImpl.java:164) at Utils.unpack0(Utils.java:364) at Utils.unpackj(Utils.java:344) at Pack200Test.doPackUnpack(Pack200Test.java:91)
28-11-2012

Likely pack200 needs some adjustments to handle IMethods.
16-11-2012