Issue with hypothetical bridge methods and JDK-6342411

Liam Miller-Cushon cushon at google.com
Mon Aug 3 21:26:32 UTC 2015


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/20150803/d9c6ede0/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: HypotheticalBridge6342411.patch
Type: application/octet-stream
Size: 8394 bytes
Desc: not available
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20150803/d9c6ede0/HypotheticalBridge6342411-0001.patch>


More information about the compiler-dev mailing list