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

David Holmes david.holmes at oracle.com
Thu Jan 30 02:43:09 PST 2014


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.

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