RFR(S): JDK-8033126 : Can't call default methods from JNI
David Holmes
david.holmes at oracle.com
Thu Jan 30 04:12:44 PST 2014
On 30/01/2014 9:39 PM, Staffan Larsen wrote:
>
> On 30 jan 2014, at 11:43, David Holmes <david.holmes at oracle.com
> <mailto: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>
>>> <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.
Indeed. I hadn't realized it was quite this liberal in allowing
arbitrary method execution. Caveat Emptor.
In that case Reviewed.
Thanks,
David
> /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