JDK-8033126 : Can't call default methods from JNI
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 8
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2014-01-29
  • Updated: 2016-04-20
  • Resolved: 2014-02-26
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 8 JDK 9
8u20 b04Fixed 9Fixed
Related Reports
Relates :  
Relates :  
Description
Reported at: http://mail.openjdk.java.net/pipermail/hotspot-dev/2014-January/012320.html

interface A {
    default int getOne() {
        return 1;
    }
}

class Impl implements A {
    public int getOne() {
        return 2;
    }
}

It is not possible to call A.getOne() using JNI since CallNonvirtual<type>Method() does not consider default methods.

Comments
Release team: Approved for deferral.
31-01-2014

JNI already has the ability to invoke an arbitrary supertype method regardless of what the Java language rules would cause to be executed in Java: http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html#wp4581 "The CallNonvirtual<type>Method families of routines and the Call<type>Method families of routines are different. Call<type>Method routines invoke the method based on the class of the object, while CallNonvirtual<type>Method routines invoke the method based on the class, designated by the clazz parameter, from which the method ID is obtained. The method ID must be obtained from the real class of the object or from one of its superclasses." This bug is modifying that code to also allow default methods to be invoked in the same. Sorry for the noise on this one. I was surprised to find JNI was allowed to do this, but then how else could a debugger invoke arbitrary methods. Aside: the JNI spec quoted above needs to be updated to reflect the fact that interface/default methods are accommodated. At a minimum change superclasses -> supertypes. But it is likely that numerous changes are need to allow for the existence of interface/default methods.
31-01-2014

Perhaps it should be possible, but only under the same constraints. It isn't clear to me that the JNI API can actually accommodate this new variation of method invocation.
30-01-2014

In Java I can do B.super.getOne() to call the implementation in B - should be possible via JNI as well.
30-01-2014

I don't think this is valid. Default methods can not be invoked arbitrarily. The only legal call above is Impl.getOne which returns 2.
30-01-2014

Attached a test case. Compile and run with: $ javac ImplTest.java $ javah ImplTest $ gcc -shared -g -o libimpl.dylib -I $JAVA_HOME/include/ -I $JAVA_HOME/include/darwin/ impl.c $ java ImplTest
29-01-2014

8-defer-request: This is an omission in the JNI interface. It is, however, not very common to have to call a default method from a super interface. See also JDK-8031195.
29-01-2014