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

contradiction in description of invokevirtual/invokespecial instructions



    • Subcomponent:
    • CPU:
    • OS:


      Name: vrR10176 Date: 06/28/2001

      The CHAPTER 6 "The Java Virtual Machine Instruction Set" of JVM-2 spec says
      about invokevirtual instruction:
          The unsigned indexbyte1 and indexbyte2 are used to construct an index into the runtime constant
      pool of the current class (?3.6), where the value of the index is (indexbyte1 << 8) | indexbyte2.
      The runtime constant pool item at that index must be a symbolic reference to a method (?5.1), which
      gives the name and descriptor (?4.3.3) of the method as well as a symbolic reference to the class in
      which the method is to be found. The named method is resolved (? The method must not be an (*1)
      instance initialization method (?3.9) or the class or interface initialization method (?3.9).
      Finally, if the resolved method is protected (?4.6), and it is either a member of the current class
      or a member of a superclass of the current class, then the class of objectref must be either the
      current class or a subclass of the current class.

          Let C be the class of objectref. The actual method to be invoked is selected by the following (*2)
      lookup procedure:
        If C contains a declaration for an instance method with the same name and descriptor as the resolved
      method, and the resolved method is accessible from C, then this is the method to be invoked, and the
      lookup procedure terminates.
        Otherwise, if C has a superclass, this same lookup procedure is performed recursively using the
      direct superclass of C; the method to be invoked is the result of the recursive invocation of this
      lookup procedure.
        Otherwise, an AbstractMethodError is raised.

      ... skip ...

      Linking Exceptions
        During resolution of the symbolic reference to the method, any of the exceptions pertaining to
      method resolution documented in Section can be thrown.
        Otherwise, if the resolved method is a class (static) method, the invokevirtual instruction
      throws an IncompatibleClassChangeError.

      Runtime Exceptions
        Otherwise, if objectref is null, the invokevirtual instruction throws a NullPointerException.
        Otherwise, if no method matching the resolved name and descriptor is selected, invokevirtual
      throws an AbstractMethodError. (*3)
        Otherwise, if the selected method is abstract, invokevirtual throws an AbstractMethodError.
        Otherwise, if the selected method is native and the code that implements the method cannot
      be bound, invokevirtual throws an UnsatisfiedLinkError. "

      The CHAPTER 6 "Loading, Linking, and Initializing" of JVM-2 spec says
      about Method Resolution:
      " Method Resolution
          To resolve an unresolved symbolic reference from D to a method in a class C, the symbolic
      reference to C given by the method reference is first resolved (? Therefore, any exceptions
      that can be thrown due to resolution of a class reference can be thrown as a result of method resolution.
      If the reference to C can be successfully resolved, exceptions relating to the resolution of the method
      reference itself can be thrown.

      When resolving a method reference:
        1.Method resolution checks whether C is a class or an interface.
          If C is an interface, method resolution throws an IncompatibleClassChangeError.
        2.Method resolution attempts to look up the referenced method in C and its superclasses:
          If C declares a method with the name and descriptor specified by the method reference, method
            lookup succeeds.
          Otherwise, if C has a superclass, step 2 of method lookup is recursively invoked on the direct
            superclass of C.
        3.Otherwise, method lookup attempts to locate the referenced method in any of the superinterfaces
            of the specified class C.
          If any superinterface of C declares a method with the name and descriptor specified by the method
            reference, method lookup succeeds.
          Otherwise, method lookup fails.

      If method lookup fails, method resolution throws a NoSuchMethodError. If method lookup succeeds and (*4)
      the method is abstract, but C is not abstract, method resolution throws an AbstractMethodError.
      Otherwise, if the referenced method is not accessible (?5.4.4) to D, method resolution throws an

      According to lookup procedure (see *2) if method lookup fails then AbstractMethodError is raised
      (see also assertion *3). But the invokevirtual instruction description says "The named method is
      resolved (?"(see *1). The section " Method Resolution" also describes lookup
      procedure and it says "If method lookup fails, method resolution throws a NoSuchMethodError."(see *4).
      This looks like a contradiction.

      Moreover api spec (jdk1.4.0beta-b69) says about the class java.lang.AbstractMethodError:

      "public class AbstractMethodError extends IncompatibleClassChangeError

      Thrown when an application tries to call an abstract method. Normally,
      this error is caught by the compiler; this error can only occur at run time
      if the definition of some class has incompatibly changed since the currently
      executing method was last compiled."

      So AbstractMethodError may be thrown when an application tries to call an abstract method.

      All JDKs since 1.2 throw NoSuchMethodError if method lookup fails. Bug #4306242 against runtime
      (Synopsis: NoSuchMethodError instead of AbstractMethodError) was closed as not a bug.

      The same issue is with invokespecial instruction.



          Issue Links



              gbrachasunw Gilad Bracha (Inactive)
              rslasunw Rsla Rsla (Inactive)
              0 Vote for this issue
              0 Start watching this issue