Issue with hypothetical bridge methods and JDK-6342411

Liam Miller-Cushon cushon at google.com
Fri Aug 7 17:16:28 UTC 2015


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> 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/20150807/819eac47/attachment-0001.html>


More information about the compiler-dev mailing list