An undefined behavior w.r.t. <clinit>
Alex Buckley
alex.buckley at oracle.com
Mon Jul 20 21:26:46 UTC 2015
Yuting,
In a 51.0 class file, a method called <clinit> whose ACC_STATIC flag is
not set is NOT a class or interface initialization method. It's just an
ordinary method that happens to be uncallable. There's nothing
"undefined" about that. Since it's an ordinary method, it can be
ACC_ABSTRACT and have no Code attribute, so J9 is wrong to throw a CFE
for it.
It just so happens that Oracle engineers were investigating methods
called <clinit> earlier this month. I filed a spec clarification:
https://bugs.openjdk.java.net/browse/JDK-8130682
Alex
On 7/8/2015 5:21 PM, Yuting Chen wrote:
> Hello, I recently feel puzzling about the JVM behaviors when an illegal
> <clinit> is met. The specification may not be complete in this part.
>
> In the specification (jvms-2.9, se8), we have the words: "In a class file
> whose version number is 51.0 or above, the method must additionally have
> its ACC_STATIC flag (§4.6) set in order to be the class or interface
> initialization method."
>
> However, the behavior is undefined if the ACC_STATIC flag is not set. Thus
> when a class without an ACC_STATIC flag may either be accepted or be
> rejected, depending on the JVM developers. The results can be unpredictable.
>
> I checked this by running a class on OpenJDK8-HotSpot and IBM J9, and found
> different results. The class can be run on HotSpot without triggering any
> exceptions (i.e., <clinit> is of no consequence). However, IBM J9 can throw
> out a FormatError (Exception in thread "main" java.lang.ClassFormatError:
> JVMCFRE074 no Code attribute specified; class=M1436188543,
> method=<clinit>()V, pc=0). I checked the specification and still could not
> decide which JVM behaves correctly.
>
> The class is attached, and the decompiled code is given next:
>
> class M1436188543
> minor version: 0
> major version: 51
> flags: ACC_SUPER
> Constant pool:
> #1 = Utf8 java/lang/Object
> #2 = Utf8 <clinit>
> #3 = Utf8 SourceFile
> #4 = Utf8 M1436188543
> #5 = Utf8 main
> #6 = Class #4 // M1436188543
> #7 = Utf8 Code
> #8 = Utf8 ([Ljava/lang/String;)V
> #9 = Utf8 ()V
> #10 = Utf8 Jasmin
> #11 = Class #1 // java/lang/Object
> {
> public abstract {};
> descriptor: ()V
> flags: ACC_PUBLIC, ACC_ABSTRACT
>
> public static void main(java.lang.String[]);
> descriptor: ([Ljava/lang/String;)V
> flags: ACC_PUBLIC, ACC_STATIC
> Code:
> stack=0, locals=1, args_size=1
> 0: return
> }
>
More information about the jls-jvms-spec-comments
mailing list