JDK-8199585 : A ClassFormatError, rather than a VerifyError
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 9,10,11
  • Priority: P3
  • Status: Resolved
  • Resolution: Not an Issue
  • OS: generic
  • CPU: generic
  • Submitted: 2018-03-13
  • Updated: 2019-06-20
  • Resolved: 2018-03-22
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 11
11Resolved
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :


FULL OS VERSION :
Linux ubuntu 4.10.0-42-generic #46-Ubuntu SMP Mon Dec 4 14:38:01 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

Windows 10.0.14393

A DESCRIPTION OF THE PROBLEM :
I got a test case. Run CTest.class on HotSpot (JRE 1.8.0_161/162), HotSpot (JRE 9.0.4). HotSpot for Java 9 reports a format error, while HotSpot for Java 8 reports a verify error (Inconsistent stackmap frames). May you check the reason?

Besides, I also ran the class on OpenJ9. A ClassFormatError was reported.

REGRESSION.  Last worked in version 8u161

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
run java CTest

ERROR MESSAGES/STACK TRACES THAT OCCUR :
HotSpot for Java 9 
java.lang.ClassFormatError: Illegal class name "Ljava/lang/Object;" in class file CTest

HotSpot for Java 8
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.VerifyError: Inconsistent stackmap frames at branch target 23
Exception Details:
Location:
CTest.f2([Ljava/lang/String;)V @23: goto
...

OpenJ9:
Error: LinkageError occurred while loading main class CTest
java.lang.ClassFormatError: JVMCFRE068 class name is invalid; class=CTest, offset=0

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
I created the class by myself. It can be downloaded at: https://jbox.sjtu.edu.cn/l/3Jv98I
javap -verbose CTest.class
public class CTest
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Utf8 CTest
#2 = Class #1 // CTest
#3 = Utf8 java/lang/Object
#4 = Class #3 // java/lang/Object
#5 = Utf8 f
#6 = Utf8 ()I
#7 = Utf8 f2
#8 = Utf8 ([Ljava/lang/String;)V
#9 = Utf8 java/lang/ClassNotFoundException
#10 = Class #9 // java/lang/ClassNotFoundException
#11 = NameAndType #5:#6 // f:()I
#12 = Methodref #2.#11 // CTest.f:()I
#13 = Utf8 Ljava/lang/Object;
#14 = Class #13 // "Ljava/lang/Object;"
#15 = Utf8 Code
#16 = Utf8 StackMapTable
{
static void f2(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_STATIC
Code:
stack=2, locals=2, args_size=1
0: goto 23
3: invokestatic #12 // Method f:()I
6: ifne 23
9: aload_0
10: iconst_0
11: aaload
12: astore_0
13: return
14: astore_1
15: aload_0
16: iconst_0
17: aaload
18: astore_1
19: invokestatic #12 // Method f:()I
22: pop
23: goto 3
Exception table:
from to target type
3 13 14 Class java/lang/ClassNotFoundException
StackMapTable: number_of_entries = 3
frame_type = 255 /* full_frame /
offset_delta = 3
locals = [ class "Ljava/lang/Object;" ]
stack = []
frame_type = 74 / same_locals_1_stack_item /
stack = [ class java/lang/ClassNotFoundException ]
frame_type = 8 / same */
}
---------- END SOURCE ----------


Comments
JDK-9's behavior, to throw ClassFormatError exception, is correct. Starting with JDK-9, the bad class name gets correctly detected during class loading. The verifier runs when a class gets linked, which happens after loading. In this case, loading fails, so linking doesn't occur, and so the verifier does not run. JDK-8's behavior is incorrect. It should detect the bad class name and throw ClassFormatError.
22-03-2018

The change in behaviour was introduced in 9 by JDK-8148854. The name Ljava/lang/Object; is illegal but was previously treated as meaning the same as java/lang/Object
21-03-2018

Alright, any theories as to why there is a behavior change ? [~fmatte] Can you check with the reporter how this class file was produced ? Which compiler was involved ? Is there some chance we can get the source code to observe the problem in compile ?
21-03-2018

The class name is illegal because it contains a ';' character. #13 = Utf8 Ljava/lang/Object; #14 = Class #13 // "Ljava/lang/Object;"
20-03-2018

Please reassign if hotspot/runtime is not the right project. Thanks in advance.
20-03-2018

[~fmatte] How did you conclude it was introduced by JDK-8160699 ?? Javac is not in the picture at all here ?? A class has been provided which has a major version number of 52 which means it has been compiled and produced by a JDK8 compiler ?? This difference in behavior comes about because of some vm change and needs to be investigated by that team ??
20-03-2018

This issue is regression started from 9 ea b137 onwards. 8uxx reports VerifyError as expected whereas JDK9 and above reports as ClassFormatError == Output from 8u172 == Error: A JNI error has occurred, please check your installation and try again Exception in thread "main" java.lang.VerifyError: Inconsistent stackmap frames at branch target 23 ==Output from 11 ea b03 == Error: LinkageError occurred while loading main class CTest java.lang.ClassFormatError: Illegal class name "Ljava/lang/Object;" in class file CTest == Regression details == 8uxx - Pass 9 ea b136 - Pass 9 ea b137 - Fail --> Regression introduced here 9 GA - Fail 9.0.4 - Fail 10 ea b44 - Fail 11 ea b03 - Fail This issue is introduced by JDK-8160699
14-03-2018