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