JDK-8167336 : Handling of static interface methods in JDI ObjectReference.invokeMethod is incorrect and incomplete
  • Type: Bug
  • Component: core-svc
  • Sub-Component: debugger
  • Affected Version: 8u40,9
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • Submitted: 2016-10-07
  • Updated: 2019-06-21
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 14
14Unresolved
Related Reports
Relates :  
Relates :  
Description
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 believe JDK-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.