Verification of non-<init> invokespecial is expected to ensure that the referenced class is the current class, a superclass of the current class, or a direct superinterface of the current class (JVMS 4.9.2).
The specified mechanism for this check relied on subtyping, which is not quite right, and didn't account for interface methods. JVMS is being updated to directly test that the referenced class is one of the allowed classes (JDK-8122946).
HotSpot behavior since Java 8 seems to be to handle Methodrefs with a subtyping check, and InterfaceMethodrefs by matching a direct superinterface. This leaves a hole: a Methodref could name any interface, and the verifier would consider the current class to be a subtype of that interface. Verification would succeed, and an error would only occur at resolution.
The implementation of this check should be simplified to just test whether the class name given by the Methodref or InterfaceMethodref is:
1) the name of this class, the direct superclass, a direct superinterface; or
2) a name that, when loaded by the current loader*, produces one of the indirect superclasses
(*To avoid unnecessary loading, (2) should first test whether any indirect superclass has a matching name.)
The specified mechanism for this check relied on subtyping, which is not quite right, and didn't account for interface methods. JVMS is being updated to directly test that the referenced class is one of the allowed classes (JDK-8122946).
HotSpot behavior since Java 8 seems to be to handle Methodrefs with a subtyping check, and InterfaceMethodrefs by matching a direct superinterface. This leaves a hole: a Methodref could name any interface, and the verifier would consider the current class to be a subtype of that interface. Verification would succeed, and an error would only occur at resolution.
The implementation of this check should be simplified to just test whether the class name given by the Methodref or InterfaceMethodref is:
1) the name of this class, the direct superclass, a direct superinterface; or
2) a name that, when loaded by the current loader*, produces one of the indirect superclasses
(*To avoid unnecessary loading, (2) should first test whether any indirect superclass has a matching name.)
- relates to
-
JDK-8026065 InterfaceMethodref for invokespecial must name a direct superinterface
-
- Closed
-
-
JDK-8026299 Lambda: Invokespecial gets an IncompatibleClassChangeError when it should get AbstractMethodError
-
- Closed
-
-
JDK-8122946 4.10.1.9: invoke{special,static} can invoke an interface method
-
- In Progress
-
- links to
-
Review(master) openjdk/jdk/25538