RFR(S): JDK-8033126 : Can't call default methods from JNI (original) (raw)

Staffan Larsen staffan.larsen at oracle.com
Thu Jan 30 03:39:53 PST 2014


On 30 jan 2014, at 11:43, David Holmes <david.holmes at oracle.com> wrote:

Hi Staffan,

On 30/01/2014 6:01 PM, Staffan Larsen wrote:

On 30 jan 2014, at 01:51, David Holmes <david.holmes at oracle.com_ _<mailto:david.holmes at oracle.com>> wrote:

Hi Staffan,

On 29/01/2014 11:17 PM, Staffan Larsen wrote: This is a more formal review request for the patch proposed in [0]

webrev: http://cr.openjdk.java.net/~sla/8033126/webrev.00/ bug: https://bugs.openjdk.java.net/browse/JDK-8033126 The bug report has a reproducer/testcase that I have used to verify the fix. I have also run the vm/jni tests in the JCK. This whole scenario doesn't look right to me. You can't arbitrarily invoke default methods in a class hierarchy. Given the testcase: interface A { default int getOne() { return 1; } } interface B extends A { default int getOne() { return 2; } } abstract class Abstract implements B { } class Impl extends Abstract { public int getOne() { return 3; } } class Impl2 extends Impl { public int getOne() { return 4; } } public class ImplTest { public static void main(String[] args) { System.loadLibrary("impl"); Impl2 i = new Impl2(); test(i); } static native void test(Impl i); } The only legitimate call is Impl2.getOne() which should return 4. What I am trying to mimic here (and which must be possible to do from JNI because debuggers need to do it) is the Java construct "B.super.getOne()” which you can call from anywhere B is implemented to actually call getOne() in B. I think the CallNonvirtualMethod()s are supposed to disregard the “normal” virtual lookup of methods and allow the caller to pick and choose. "The /CallNonvirtualMethod/ families of routines and the /CallMethod/ families of routines are different. /CallMethod/ routines invoke the method based on the class of the object, while/CallNonvirtualMethod/ 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.” Hmmmm. So this allows you to call any inherited version of the method on a given object regardless? If so then it seems we're throwing out the normal accessibility and overriding rules. I can see the need to be able to invoke super.foo() but this seems to give you the ability to effectively do super.super.foo() - which violates the language rules. If that is the case then allowing the same for default methods is consistent. But I'm troubled if this is indeed the case.

I believe this is indeed the case. And, yes, I want to extend it to default methods. JNI allows you to do stuff that you can’t normally do from Java.

/Staffan

David

Thanks, /Staffan

David ----- Thanks, /Staffan [0] http://mail.openjdk.java.net/pipermail/hotspot-dev/2014-January/012325.html



More information about the hotspot-dev mailing list