Incorrect CONSTANT_Class format when writing frame types. Fails to pass Java 9 validation.
ClassWriter#newClass is called.
The method should normally take the internal name of the class, e.g.
L and appends
;, passing the descriptor instead. This is inconsistent with the class file format.
In Java 8 virtual machines (and below), this wasn't a problem because the VM did not strictly validate the format of a Class constant. However, Java 9 virtual machines do impose this restriction, resulting in a ClassFormatError, such as the following:
Error: LinkageError occurred while loading main class Test java.lang.ClassFormatError: Illegal class name "Ljava/lang/Object;" in class file Test
Can you give a more concrete example? writeFrameTypes uses "L...;" only for array element types (which can also be primitive types I,J,D,etc), which are preceded by one or more "[". Maybe the issue comes from somewhere else, and a concrete example could help find the root cause.
I'll be able to provide a concrete example later on this week:
After taking a look at the code, it seems that the dimension is stored in the first part of the first byte of the frame bitfield: if the first bit is set, the entire integer would be negative and the arithmetic shift on
MethodWriter.java:1903would populate the left side with '1's instead of '0'.
The issue was found with a conditional breakpoint set at ClassWriter#newClass, looking for an argument strictly equal to
MethodWriter.java:1938was the caller.