Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8130682

2.9: Clarify class and interface initialization methods

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P4
    • Resolution: Fixed
    • Affects Version/s: 8
    • Fix Version/s: 9
    • Component/s: specification
    • Labels:
    • Subcomponent:
      vm

      Description

      The clause "Other methods named <clinit> in a class file are of no consequence." has caused an unreasonable amount of confusion. It turns out that when HotSpot parses a method_info structure, it accepts a descriptor for a void <clinit> which stupidly takes arguments (following the "no consequence" rule) but throws CFE for a descriptor for a non-void <clinit>. This is inconsistent and arbitrary. Furthermore, HotSpot performs format checking on the attributes of the method_info whose descriptor is void <clinit> with arguments, leading to CFE if the attributes are malformed or otherwise illegal (e.g. method_info.access_flags indicates ACC_NATIVE but a Code attribute exists) -- so in fact the method is of consequence.

      Rather than asking a JVM to understand three kinds of methods:
      - Class or interface initialization methods
      - Stupid methods called <clinit> that aren't class or initialization methods (because they're non-void, or because they're void but take arguments)
      - All other methods
      a JVM should only have to distinguish two kinds of methods:
      - Class or interface initialization methods
      - All other methods

      2.9 should say:
      - A class or interface has at most one class or interface initialization method, and is initialized by ***the Java Virtual Machine*** invoking that method (§5.5).
      - A method is a _class or interface initialization method_ if all of the following are true:
        - It has the special name <clinit>.
        - It is void (§4.3.3).
        - In a class file whose version number is 51.0 or above, the method has its ACC_STATIC flag (§4.6) set and takes no arguments. (Note: The requirement for ACC_STATIC was introduced in Java SE 7, and for taking no arguments in Java SE 9.)
      - Other methods named <clinit> in a class file are not class or interface initialization methods. They cause CFE in HotSpot [Note: this is true for non-void <clinit> since JDK 6 at least; unfortunately HotSpot allowed void <clinit> with arguments as recently as JDK 8 -- there is no reason to accept such bad methods so JVMS9 bans them in a moderately compatible manner, i.e. for >=51.0], so should be prohibited in 4.6 on the basis of their method descriptor. They are never invoked by the Java Virtual Machine itself, and cannot be invoked by any Java Virtual Machine instruction (4.9.1).

      Related change in 4.6: "Class and interface initialization methods are called implicitly by the Java Virtual Machine, whereupon the value of their access_flags item is ignored except for the setting of the ACC_STRICT flag. Because the value of their access_flags item is irrelevant (except for the ACC_STRICT flag), class and interface initialization methods are exempt from the preceding rules about legal combinations of flags."

      Related change in 4.7.3: Because access_flags are irrelevant, a class or interface initialization method can have ACC_NATIVE or ACC_ABSTRACT set and still have a Code attribute. 4.7.3 should specify that class and interface initialization methods must have exactly one Code attribute regardless of the value of access_flags.

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                abuckley Alex Buckley
                Reporter:
                asolodkaya Anastasiya Solodkaya (Inactive)
              • Votes:
                0 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: