Issue with hypothetical bridge methods and JDK-6342411
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Mon Aug 10 09:36:59 UTC 2015
Filed:
https://bugs.openjdk.java.net/browse/JDK-8133247
Maurizio
On 07/08/15 18:16, Liam Miller-Cushon wrote:
> I think this is about as likely to be observed as JDK-6924232, which
> doesn't seem to be causing anyone major problems. On the other hand
> this issue would be very easy to fix.
>
> Do you think the current approach will be replaced soon enough that it
> isn't worth tracking this? If not, is anyone willing to file a
> tracking bug or review my patch?
>
> On Wed, Aug 5, 2015 at 1:58 PM, Maurizio Cimadamore
> <maurizio.cimadamore at oracle.com
> <mailto:maurizio.cimadamore at oracle.com>> wrote:
>
> This is related to the discussion we had; a long tail of the
> current approach for bridge calculation is that sometimes we need
> hypothetical stuff which is there just to make
> Symbol.binaryOverrides work correctly. I'm not completely
> surprised this sometimes lead to unexpected behavior...
>
> Maurizio
>
>
> On 03/08/15 22:26, Liam Miller-Cushon wrote:
>
> I think I found a bug in the interaction between
> 'hypothetical' bridge methods and the workaround for JDK-6342411.
>
> A hypothetical bridge method "is not strictly necessary in the
> binary, but is represented in the symbol table to detect
> erasure clashes." [1]
>
> Bridges are required to work around JDK-6342411 when a
> non-public super class declares a public method that's
> inherited into a public derived class. Without the bridge,
> reflectively invoking the method on the derived class fails
> with `IllegalAccessException: can not access a member with
> modifiers "public"`. [2][3]
>
> The issue I found occurs when a bridge method candidate
> qualifies as a hypothetical bridge *and* is necessary to work
> around JDK-6342411. The path for hypothetical bridges wins, so
> the bridge is entered in the symbol table but not generated in
> the binary, and attempts to invoke it reflectively fail.
>
> I've attached a patch with a regression test and a possible fix.
>
> Here's the repro:
>
> === ./p/I.java ===
> package p;
>
> public interface I<T> {
> void f(T t);
> }
> === ./p/B.java ===
> package p;
>
> public class B extends A<String> {}
> === ./p/A.java ===
> package p;
>
> class A<T> implements I<T> {
> public void f(T t) {}
> }
> === ./Test.java ===
> import java.lang.reflect.Method;
>
> public class Test {
> public static void main(String[] args) throws Exception {
> Method m = Class.forName("p.B").getMethod("f", Object.class);
> m.invoke(new p.B(), new Object[]{null});
> }
> }
> ===
>
> $ javac p/I.java p/A.java p/B.java Test.java
> $ java Test
> Exception in thread "main" java.lang.IllegalAccessException:
> Class Test can not access a member of class p.A 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 Test.main(Test.java:6)
>
> [1]
> http://hg.openjdk.java.net/jdk9/dev/langtools/file/7eef740c1482/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java#l238
> [2]
> http://hg.openjdk.java.net/jdk9/dev/langtools/file/7eef740c1482/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java#l364
> [3] https://bugs.openjdk.java.net/browse/JDK-6342411
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20150810/c755a41b/attachment.html>
More information about the compiler-dev
mailing list