JDK-4207233 : (reflect) can't use reflection to invoke private method in outer class
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang:reflect
  • Affected Version: 1.2.0,1.3.0
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic,windows_nt
  • CPU: generic,x86
  • Submitted: 1999-01-29
  • Updated: 2012-09-28
  • Resolved: 2002-04-24
Related Reports
Duplicate :  
Description

Name: diC59631			Date: 01/29/99


I have been unable (so far) to replicate the problem without using the
Maps (this also fails on a TreeMap), though it *should* be possible.
Other implementations may not encounter this problem, as it seems to be
related somehow to the structure being used in the HashMap.

import java.lang.reflect.*;
import java.util.*;

public class Class1
{
  public final static Class[] EMPTY_PARAMETERS = {};

  public static void main( String argv[] ) throws Exception
  {
// This works perfectly 
  
    {
      HashMap source = new HashMap();
      Set obj = source.keySet();
      System.out.println( obj.iterator() );
    }

// Here is what does not work
  
    {
      Object source = new HashMap();
      Method source_method = source.getClass().getMethod( "keySet", EMPTY_PARAMETERS );
      Object obj = source_method.invoke( source, EMPTY_PARAMETERS );
      Method obj_method = obj.getClass().getMethod( "iterator", EMPTY_PARAMETERS );
      System.out.println( obj_method.invoke( obj, EMPTY_PARAMETERS ) );
    }
  }
}

Under JDK1.2 for Windows this returned:

java.util.HashMap$HashIterator@757466d1

java.lang.IllegalAccessException: java/util/HashMap$1

	at java.lang.reflect.Method.invoke(Native Method)

	at Class1.main(Class1.java:31)

Exception in thread "main" Process Exit...
(Review ID: 52621)
======================================================================

Name: tb29552			Date: 11/03/2000


/*
bash-2.04$ java -version
java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)

Why can't reflection be used to invoke a private method on the outer class
just as one can invoke such a method in compile code. In the following
example the line
    method1(); // XXXX

should be equivalent to the line
    m.invoke(R.this, args); // YYYY

but they are not as seen by running the example. Why should this be?

bash-2.04$ cat R.java
*/
import java.lang.reflect.*;
class R {
    class A {
        A() throws Exception {
            // This works
            method1(); // XXXX
            Class c = R.class;
            Class[] types = {};
            Method m = c.getDeclaredMethod("method1", types);
            Object[] args = {};
            // Why doesn't this work
            m.invoke(R.this, args); // YYYY
        }
    }
    R() throws Exception {
        A a = new A();
    }

    private void method1() {
        System.out.println("method1");
    }

    public static void main(String[] args) throws Exception {
        R r = new R();
    }
}
/*
  bash-2.04$ java R
  method1
  Exception in thread "main" java.lang.IllegalAccessException
      at java.lang.reflect.Method.invoke(Native Method)
      at R$A.<init>(R.java:16)
      at R.<init>(R.java:21)
      at R.main(R.java:31)
*/
(Review ID: 111760)
======================================================================

Comments
EVALUATION Looks to me like a reflection bug. joshua.bloch@Eng 1999-02-01 Reflection is clearly doing the reflective access check differently than in the non-reflective case. I verified that the 1.2 on Solaris yields the same behavior even with -Xverify:all specified, suspecting that this might be an access method bug. I'm not going to investigate a compiler problem, however, until someone tells me why reflection might do a more thorough check than -Xverify:all. william.maddox@Eng 1999-02-11 $ java -version java version "1.4.1-beta" Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1-beta-b10) Java HotSpot(TM) Client VM (build 1.4.1-beta-b10, mixed mode) $ java Class1 java.util.HashMap$KeyIterator@601bb1 Exception in thread "main" java.lang.IllegalAccessException: Class Class1 can not access a member of class java.util.HashMap$KeySet with modifiers "public" at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:57) at java.lang.reflect.Method.invoke(Method.java:317) at Class1.main(Class1.java:25) $ java R method1 Exception in thread "main" java.lang.IllegalAccessException: Class R$A can not access a member of class R with modifiers "private" at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:57) at java.lang.reflect.Method.invoke(Method.java:317) at R$A.<init>(R.java:12) at R.<init>(R.java:16) at R.main(R.java:24) Duplicate of bug 4071957. -- iag@sfbay 2002-04-24
24-04-2002