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
---
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
- is blocked by
-
JDK-8024750 Require receiver of invokespecial to be an instance of the current class?
-
- Closed
-