United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-4071957 : (reflect) Method.invoke access control does not understand inner class scoping

Details
Type:
Bug
Submit Date:
1997-08-14
Status:
Open
Updated Date:
2014-08-19
Project Name:
JDK
Resolved Date:
Component:
core-libs
OS:
windows_nt,solaris_2.5.1,linux,generic,windows_xp,windows_2000
Sub-Component:
java.lang:reflect
CPU:
x86,sparc,generic
Priority:
P4
Resolution:
Unresolved
Affected Versions:
1.1.1,1.1.3,1.1.6,1.1.8,1.2.0,1.3.0,1.3.1,1.4.0,1.4.1,6u27,7,8,9
Targeted Versions:
tbd_major

Related Reports
Backport:
Duplicate:
Duplicate:
Duplicate:
Duplicate:
Duplicate:
Duplicate:
Duplicate:
Relates:
Relates:
Relates:

Sub Tasks

Description
Name: sg39081			Date: 08/14/97


Running the following program, which should succeed, results in an
IllegalAccessException.

import java.lang.reflect.*;

public class TestPrivateAccess extends Object
{
  TPAInnerClass inner = new TPAInnerClass();

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

  class TPAInnerClass extends Object
  {
    void dynamicInvoke()
    {
      try
	{
	  Method method = 
TestPrivateAccess.class.getDeclaredMethod("privateMethod", new Class[] {});
	  method.invoke(TestPrivateAccess.this, new Object[] {});
	}
      catch (Exception e)
	{e.printStackTrace();}
    }
  }

  public static void main(String[] argv)
  {
    TestPrivateAccess tpa = new TestPrivateAccess();
    tpa.inner.dynamicInvoke();
  }
}

company - MIT Media Lab , email - ###@###.###
======================================================================

                                    

Comments
WORK AROUND



Name: sg39081			Date: 08/14/97



======================================================================
                                     
2004-09-04
EVALUATION

We would like to eventually extend the classfile format to eliminate
access methods; however, we've decided not to do that for 1.2 in favor
of a more sweeping change down the road that would also solve other
problems with inner classes, such as their excessive space consumption.
So this can't be fixed until after a decision has been made about revisiting
the classfile format, which will be well after 1.2.

david.stoutamire@Eng 1998-04-08

$ 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 TestPrivateAccess
java.lang.IllegalAccessException: Class TestPrivateAccess$TPAInnerClass can not access a member of class TestPrivateAccess with modifiers "private"
        at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:57)
        at java.lang.reflect.Method.invoke(Method.java:317)
        at TestPrivateAccess$TPAInnerClass.dynamicInvoke(TestPrivateAccess.java:18)
        at TestPrivateAccess.main(TestPrivateAccess.java:28)

There have been numerous reports of this problem.  One of the more notable
examples is provided in bug 4207233:

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();
    }
}

In this example, we not only see the problem but we are also confronted with the
fact that reflection is doing the reflective access check differently than the
non-reflective case.  This is because the non-reflective case is resolved by
javac where we have more information about member accessibility than is
encoded in the classfile.  It is highly questionable whether we should attempt
to replicate the javac analysis during reflection.  A much better solution is
to update the classfile format to contain the necessary information.

Tiger planning is considering the classfile format changes.

-- iag@sfbay 2002-04-24
-----------------------------

Another customer has run into similar problem in the context of Java Plugin (ActiveX bridge). See bug 4852768 for details.
There's a fix in the Java Plugin code to workaround this issue. Refer to the suggested fix section of 4852768.
Maybe a similar fix can be applied to the customer's apps. in this case as a workaround for the now while waiting for a complete fix in Tiger.

###@###.### 2003-05-01
------------------------------

I don't expect to see this fixed before Dolphin at the earliest. As noted above, it requires substantial changes to the class file format and VMs.

###@###.### 2005-05-05 18:47:22 GMT

It turns out that it is possible to implement this
with limited changes to the JVM.  With the addition of the
enclosing method info attribute in class files in JDK 5,
it is now possible to reconstruct all the required data
required by Method.invoke to check accessibility in
nested classes.  All that would be required from the JVM
is to verify that the enclosing method info attribute
is correct.

###@###.### 2005-05-06 09:49:20 GMT
                                     
2005-05-06
EVALUATION

A suggested fix has been contributed by java.net member mondo

Contribution forum : https://jdk-collaboration.dev.java.net/servlets/ProjectForumMessageView?forumID=1463&messageID=19397
                                     
2007-04-06



Hardware and Software, Engineered to Work Together