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