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