JDK-6342411 : Add bridge method to allow reflective access to public method in non-public class
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 5.0
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2005-10-27
  • Updated: 2021-04-13
  • Resolved: 2005-12-17
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6
6 b65Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
The program below fails at runtime with this error:

Exception in thread "main" java.lang.IllegalAccessException: Class refl.ClientTest can not access a member of class refl.a.Base with modifiers "public"
        at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65)
        at java.lang.reflect.Method.invoke(Method.java:578)
        at refl.ClientTest.main(ClientTest.java:9)

========== test/refl/a/Base.java ========== 
     1  package refl.a; 
     2   
     3  class Base { 
     4      public void f() { 
     5          System.out.println("Hello, world!"); 
     6      } 
     7  } 
========== test/refl/a/Pub.java ========== 
     1  package refl.a; 
     2   
     3  public class Pub extends Base {} 
========== test/refl/ClientTest.java ========== 
     1  package refl; 
     2  import refl.a.*; 
     3  import java.lang.reflect.*; 
     4   
     5  public class ClientTest { 
     6      public static void main(String[] args) throws Exception { 
     7          Pub p = new Pub(); 
     8          Method m = Pub.class.getMethod("f"); 
     9          m.invoke(p); 
    10      } 
    11  }

Comments
EVALUATION Incident ID 528582 will be evaluated in bug 6378384. Once again, thank you for bringing this to our attention.
30-01-2006

EVALUATION I don't have a bug id for the incident yet. Once I have, I'll add more information.
28-01-2006

EVALUATION In response to SDN comments: Fields can't be fixed by adding a bridge method. However, the situation with protected methods appears to be a symmetric case and I should have caught that the first time around. Thanks for pointing this out.
28-01-2006

SUGGESTED FIX --- src/share/classes/com/sun/tools/javac/comp/TransTypes.java- 2005-12-06 21:30:14.546826072 +0530 +++ src/share/classes/com/sun/tools/javac/comp/TransTypes.java 2005-12-06 21:30:14.554824856 +0530 @@ -276,10 +276,18 @@ || impl != meth && !types.isSameType(impl.erasure(types).getReturnType(), meth.erasure(types).getReturnType()))) { addBridge(pos, meth, impl, origin, bridge==impl, bridges); + } else if (impl == meth + && impl.owner != origin + && (impl.flags() & FINAL) == 0 + && (meth.flags() & (ABSTRACT|PUBLIC)) == PUBLIC + && (origin.flags() & PUBLIC) > (impl.owner.flags() & PUBLIC)) { + // this is to work around a horrible but permanent + // reflection design error. + addBridge(pos, meth, impl, origin, false, bridges); } } else if ((bridge.flags() & SYNTHETIC) != 0) { MethodSymbol other = overridden.get(bridge); if (other != null && other != meth) { if (impl == null || !impl.overrides(other, origin, types, true)) {
06-12-2005

SUGGESTED FIX *** src-original/com/sun/tools/javac/comp/TransTypes.java Thu Mar 31 19:37:38 2005 --- src/com/sun/tools/javac/comp/TransTypes.java Thu Mar 31 20:42:00 2005 *************** *** 277,282 **** --- 277,289 ---- !types.isSameType(impl.erasure(types).restype(), meth.erasure(types).restype()))) { addBridge(pos, meth, impl, origin, bridge==impl, bridges); + } else if (impl == meth && impl.owner != origin && + (meth.flags() & (ABSTRACT|PUBLIC)) == PUBLIC && + (origin.flags() & PUBLIC) > (impl.owner.flags() & PUBLIC)) + { + // this is to work around a horrible but permanent + // reflection design error. + addBridge(pos, meth, impl, origin, false, bridges); } } else if ((bridge.flags() & SYNTHETIC) != 0) { MethodSymbol other = overridden.get(bridge);
27-10-2005

EVALUATION The proposal is to add bridge methods in these very rare cases to fix a problem in reflection with no other forseen fix or workaround. Specifically, we would generate a bridge method when a public method is inherited from a nonpublic class into a public class.
27-10-2005