JDK-7120817 : Anonymous inner class, IllegalAccessException, public modifier
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang:reflect
  • Affected Version: 7
  • Priority: P4
  • Status: Closed
  • Resolution: Not an Issue
  • OS: windows_7
  • CPU: x86
  • Submitted: 2011-12-13
  • Updated: 2012-09-28
  • Resolved: 2011-12-14
Description
FULL PRODUCT VERSION :
java version "1.7.0_02"
Java(TM) SE Runtime Environment (build 1.7.0_02-b13)
Java HotSpot(TM) 64-Bit Server VM (build 22.0-b10, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]

A DESCRIPTION OF THE PROBLEM :
Invoking a method declared in anonymous inner class in another package yields IllegalAccessException.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Executable test case provided.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
failFunction() executes successfully.
ACTUAL -
Exception in thread "main" java.lang.IllegalAccessException: Class pkg1.MainClass can not access a member of class pkg2.SecondClass$1 with modifiers "public"
	at sun.reflect.Reflection.ensureMemberAccess(Unknown Source)
	at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(Unknown Source)
	at java.lang.reflect.AccessibleObject.checkAccess(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at pkg1.MainClass.main(MainClass.java:7)


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
--- pkg1\MainClass.java -------------------
package pkg1;
import pkg2.SecondClass;
public class MainClass {
	
	public static void main(String[] args) throws Exception {
		Object innerClassInstance = SecondClass.innerClassInstance;
		innerClassInstance.getClass().getMethod("failFunction").invoke(innerClassInstance);
	}

}

--- pkg2\SecondClass.java -------------------
package pkg2;
public class SecondClass {

	public static Object innerClassInstance = new Object() {
		public void failFunction() {
			System.out.println("Hello World!");
		}
	};
	
}

---------- END SOURCE ----------

Comments
EVALUATION This is not a bug, and the behavior is the same in previous releases. The reflection accessibility check is correctly failing as the anonymous inner class is package-private, and therefore not accessible to pkg1.MainClass. Below is the output of javap: >: ./bin/javap pkg2.SecondClass\$1 Compiled from "SecondClass.java" final class pkg2.SecondClass$1 extends java.lang.Object{ pkg2.SecondClass$1(); public void failFunction(); } For this to work MainClass should suppress the Java language access checking by invoking setAccessible(true) on the method: package pkg1; import java.lang.reflect.*; import pkg2.SecondClass; public class MainClass { public static void main(String[] args) throws Exception { Object innerClassInstance = SecondClass.innerClassInstance; Method m = innerClassInstance.getClass().getMethod("failFunction"); m.setAccessible(true); ///<<<<<<<<<<<<<<<<< m.invoke(innerClassInstance); } } The Eclipse compiler generates the same package-private anonymous inner class.
14-12-2011