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

invokespecial triggers surprising VerifyError

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Not an Issue
    • Icon: P3 P3
    • 9
    • 7u5
    • hotspot
    • None
    • generic
    • generic

      invokespecial seems to have a restriction that it only be used on a method in a superclass of the calling class (with the exception of <init> calls); and even then, the receiver must be an instance of the calling class. I can't find where this is specified in the JVMS; I asked a few other experts who didn't have an explanation.

      ---

      public class A {
        public void m() { System.out.println("A.m"); }
      }

      public class Test {
        public static void main(String[] args) {
          new A
          dup
          invokespecial A/<init>()V
          invokespecial A/m()V
        }
      }

      ---

      Exception in thread "main" java.lang.VerifyError: Bad invokespecial instruction: current class isn't assignable to reference class. in method Test.main([Ljava/lang/String;)V at offset 7
      at java.lang.Class.getDeclaredMethods0(Native Method)
      at java.lang.Class.privateGetDeclaredMethods(Class.java:2442)
      at java.lang.Class.getMethod0(Class.java:2685)
      at java.lang.Class.getMethod(Class.java:1620)
      at sun.launcher.LauncherHelper.getMainMethod(LauncherHelper.java:492)
      at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:484)

      ---

      If I change Test to extend A:

      Exception in thread "main" java.lang.VerifyError: Bad type on operand stack in method Test.main([Ljava/lang/String;)V at offset 7
      at java.lang.Class.getDeclaredMethods0(Native Method)
      at java.lang.Class.privateGetDeclaredMethods(Class.java:2442)
      at java.lang.Class.getMethod0(Class.java:2685)
      at java.lang.Class.getMethod(Class.java:1620)
      at sun.launcher.LauncherHelper.getMainMethod(LauncherHelper.java:492)
      at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:484)

      ---

      This seems to be longstanding behavior -- similar errors occur in 1.6.0, 1.5.0, 1.4.2, and 1.3.0. But so far as I've been able to determine, it's an unspecified restriction.

      Possible outcomes:
      - Find the restriction in JVMS
      - Make a specification change, adding the restriction to JVMS
      - Remove the verification logic, accepting that it is non-compliant
      - This is an "extra", optional verification step, and there's a flag I can use to get JVMS-compliant behavior

        1. TestInvokeSpecial.java
          5 kB
        2. B.class
          0.2 kB
        3. A.class
          0.3 kB

            lfoltan Lois Foltan
            dlsmith Dan Smith
            Votes:
            0 Vote for this issue
            Watchers:
            7 Start watching this issue

              Created:
              Updated:
              Resolved: