An undefined behavior w.r.t. <clinit>

Gilles Duboscq duboscq at ssw.jku.at
Sun Jul 12 11:36:36 UTC 2015


Hi Yuting,

I think the behaviour is well defined even if the <clinit> method is not
ACC_STATIC: in this case if the class version is >= 51.0 then this method
is *not* the special "class initializer" method and it will not be called
during class initialization.

To cite jvms: "Other methods named <clinit> in a class file are of no
consequence. They are not class or interface initialization methods."
I do not think the JVM should throw any exception because of this.

Your example is interesting for an other reason though. The class file was
stripped by the mailing list system but from the javap dump it looks like
your <clinit> method is abstract and has no code.
If the class file version was < 51.0, i'm not exactly sure what should
happen.

 Gilles

On Fri, Jul 10, 2015 at 11:34 PM Yuting Chen <chenyt.cs.sjtu at gmail.com>
wrote:

> >>Reported to jls-jvms-spec-comments, and so far no response.
> >>Thus I report the problem here again.
>
> 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.
>
> (I thought the question again, and believed that it can be better if
> HotSpot can also report a ClassFormatError.)
>
> 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 hotspot-runtime-dev mailing list