Changes to JDI for static and default interface methods was added under JDK-8042123. But while investigating the changes needed for private interface methods in JDK-8165827 it became apparent that the specification with respect to static interface methods was incorrect. It states:
* @throws java.lang.IllegalArgumentException if the method is not
* a member of this object's class, if the size of the argument list
* does not match the number of declared arguments for the method,
* if the method is a constructor or static intializer, or
* if {@link #INVOKE_NONVIRTUAL} is specified and the method is
* either abstract or a non-default interface member.
The last clause prohibits nonvirtual invocation of a static interface method, but it should be allowed according to the initial spec for the method:
/**
* Invokes the specified {@link Method} on this object in the
* target VM. The
* specified method can be defined in this object's class,
* in a superclass of this object's class, or in an interface
* implemented by this object. The method may be a static method
* or an instance method, but not a static initializer or constructor.
The implementation seems to support this as it delegates static method invocations to Interfacetype.invokeMethod or ClassType.invokeMethod as appropriate.
That said it is unclear why only non-virtual invocations would be affected.
On further reflection and examination of what is allowed at the Java language level I think the intent was that static interface methods can not be invoked via ObjectReference.invokeMethod, but the changes to the spec and the implementation were not consistent with that. I believeJDK-8042123 should have:
a) Changed the initial part of the invokeMethod spec from:
"The method may be a static method or an instance method, but not a static initializer or constructor."
to read something like:
"The method may be a static class method or an instance method, but not a static initializer, static interface method or constructor."
and
b) Actually implemented the logic to throw IllegalArgumentException when called for a static interface method whether virtual or non-virtual
Then the logic that dispatches to InterfaceType.invokeMethod is not needed and should be removed.
And of course the @throws IllegalArgumentException should add "or is a static interface method" unconditionally.
* @throws java.lang.IllegalArgumentException if the method is not
* a member of this object's class, if the size of the argument list
* does not match the number of declared arguments for the method,
* if the method is a constructor or static intializer, or
* if {@link #INVOKE_NONVIRTUAL} is specified and the method is
* either abstract or a non-default interface member.
The last clause prohibits nonvirtual invocation of a static interface method, but it should be allowed according to the initial spec for the method:
/**
* Invokes the specified {@link Method} on this object in the
* target VM. The
* specified method can be defined in this object's class,
* in a superclass of this object's class, or in an interface
* implemented by this object. The method may be a static method
* or an instance method, but not a static initializer or constructor.
The implementation seems to support this as it delegates static method invocations to Interfacetype.invokeMethod or ClassType.invokeMethod as appropriate.
That said it is unclear why only non-virtual invocations would be affected.
On further reflection and examination of what is allowed at the Java language level I think the intent was that static interface methods can not be invoked via ObjectReference.invokeMethod, but the changes to the spec and the implementation were not consistent with that. I believe
a) Changed the initial part of the invokeMethod spec from:
"The method may be a static method or an instance method, but not a static initializer or constructor."
to read something like:
"The method may be a static class method or an instance method, but not a static initializer, static interface method or constructor."
and
b) Actually implemented the logic to throw IllegalArgumentException when called for a static interface method whether virtual or non-virtual
Then the logic that dispatches to InterfaceType.invokeMethod is not needed and should be removed.
And of course the @throws IllegalArgumentException should add "or is a static interface method" unconditionally.
- relates to
-
JDK-8165827 Support private interface methods in JNI, JDWP, JDI and JDB
- Resolved
-
JDK-8042123 Support default and static interface methods in JDI, JDWP and JDB
- Resolved