declaring class of a default method Was: Bug 8027734
Yumin Qi
yumin.qi at oracle.com
Tue Nov 12 16:19:57 UTC 2013
Thanks.
I will look back in hotspot.
Yumin
On 11/12/2013 6:25 AM, Joel Borggren-Franck wrote:
> Hi Yumin,
>
> Basically this is due to a difference in declaring class for a Method
> representing a default method vs a normal Method.
>
> On 2013-11-11, Yumin Qi wrote:
>> Hi, Joel
>>
>> This bug is a SQE testing bug, see
>> https://bugs.openjdk.java.net/browse/JDK-8027734
>> <https://bugs.openjdk.java.net/browse/JDK-8027734>
>>
>> I have commented with the exception stacktrace.
>>
> This is easy to reproduce without VM sqe frameworks:
>
> p1/I.java:
>
> package p1;
> interface I {
> default void m() {
> System.out.println("Foo!");
> }
> }
>
> p2/J.java:
>
> package p1;
> public interface J extends I {}
>
> p2/C.java:
>
> package p2;
> import p1.J;
> import java.lang.reflect.*;
> public class C {
> public static void main(String[] args) throws Exception {
> Method m = J.class.getMethod("m", (Class<?>[])null);
> System.out.println(m + " declaring class: " + m.getDeclaringClass());
> m.invoke(new J() {});
> }
> }
>
> Compiling and running this will print:
>
> $ java p2.C
> public default void p1.I.m() declaring class: interface p1.I
> Exception in thread "main" java.lang.IllegalAccessException: Class p2.C
> can not access a member of class p1.I with modifiers "public"
> at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:101)
> at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:295)
> at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:287)
> at java.lang.reflect.Method.invoke(Method.java:476)
> at p2.C.main(C.java:8)
>
> Note that the delcaring class of m is "interface p1.I".
>
> Changing this to classes instead:
>
> package p3;
> class A {
> public void m() {
> System.out.println("Foo!");
> }
> }
>
> package p3;
> public class B extends A {}
>
> package p4;
> import p3.B;
> import java.lang.reflect.*;
> public class C2 {
> public static void main(String[] args) throws Exception {
> Method m = B.class.getMethod("m", (Class<?>[])null);
> System.out.println(m + " declaring class: " + m.getDeclaringClass());
> m.invoke(new B() {});
> }
> }
>
> And running this gives:
>
> java p4.C2
> public void p3.B.m() declaring class: class p3.B
> Foo!
>
> Note that even though m is lexically declared in class A
> m.getDeclaringClass() outputs _p3.B_ as it's declaring class.
>
> I'm not sure how we should fix this, but my first impression is that the
> VM is wrong here when creating the default method Method in the
> interface example.
>
> cheers
> /Joel
More information about the core-libs-dev
mailing list