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

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 CallNonvirtual<Type>Method()s are supposed to disregard the
>> “normal” virtual lookup of methods and allow the caller to pick and choose.
>> 
>> "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.”
> 
> 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