Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4071593
Votes 30
Synopsis (reflect) Method.invoke() throws spurious IllegalAccessException
Category java:classes_lang
Reported Against 1.3 , 1.1.3
Release Fixed
State 11-Closed, duplicate of 4071957, bug
Priority: 4-Low
Related Bugs 4071957
Submit Date 13-AUG-1997
Description




I am using JDK 1.1.3 with the JDK 1.1.3 VM on NT 4.0.
I am trying to use invoke() to call hasMoreElements()
on the Enumeration (java.util.VectorEnumerator) that I
obtained from a Vector. I am getting an llegalAccessException,
although I clearly have access to call this function
through the Enumeration interface.
I believe that the problem is related to the fact that
the class VectorEnumerator is not accessible to me,
even though I can call its public functions when it
is passed to me as an Enumeration. I think that invoke()
may be checking to see if the VectorEnumeration class
is accessible, and complaining when it discovers that 
it is not. I don't know if this is true (invoke() is native,
so I can't check the source.)

(Speculation follows: ) If this is the problem, I recommend modifying 
java.lang.reflect.Method.invokeinvoke(Object obj, Object args[])
so that it only checks to see if I have access to
the class in which Method is defined if the 
Method is static, and if it is non-static then 
it just checks the function that I am calling,
to better mimic the security behaviour that the VM
uses for a regular function invocation.
(End of speculation.)

Sample code is below.



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

// Tries to use the reflection APIs to invoke Enumeration.hasMoreElements(),
// and fails miserably.	Sample output:
//
// >java test
//	java.lang.IllegalAccessException: java/util/VectorEnumerator
//		at test.main(test.java:46)

class test
{
	final static boolean HACK = false;
	
	public static void main(String[] argc)
		throws NoSuchMethodException,
			   IllegalAccessException,
			   InvocationTargetException
	{
		Vector myVector = new Vector();
		//foo myFoo = new foo();
		
		Enumeration myEnum;
		if (HACK)
			myEnum = new enumerationWrapper(myVector.elements());
		else
			myEnum = myVector.elements();
		
		// Create the Vector & Enumeration
		// If HACK, then we wrap it with out (accessible) Enumeration
		
		Class[] theArgTypes = new Class[0];
			// hasMoreElements() takes 0 parameters
		
		Class enumClass = myEnum.getClass();
			// get the class
		
        Method hasMoreElements =
			enumClass.getDeclaredMethod("hasMoreElements", theArgTypes);
			// create the Method from the class & param list
		
		Object[] theArgs = new Object[0];
			// create the parameters (there are none of them)
		
		Object result =  hasMoreElements.invoke(myEnum, theArgs);
			// try to invoke Enumeration.hasMoreElements()
		
		System.out.println("m_Method.invoke(myEnum, theArgs); == " + result);
			// we never get here unless HACK == true
	}
	
	public final static class enumerationWrapper implements Enumeration
	{
		Enumeration java_util_VectorEnumerator;
		// The Enumeration we're wrapping
		
		public enumerationWrapper(Enumeration java_util_VectorEnumerator)
		{
			this.java_util_VectorEnumerator = java_util_VectorEnumerator;
		}
	
		public boolean hasMoreElements()
		{
			return java_util_VectorEnumerator.hasMoreElements();
		}
	
		public Object nextElement()
		{
			return java_util_VectorEnumerator.nextElement();			
		}
	}

}



======================================================================
Work Around




A (hack) workaround is shown in my sample code above.
change final static boolean HACK to true, recompile,
and I can access Enumeration through the wrapper 
class that I established. This works for VectorEnumerator,
but I'll have to do this again for the next class that
I trip over that also exhibits this behaviour. I doubt
that VectorEnumerator is the only class that will
cause this problem.
======================================================================
Evaluation
$ 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 test
Exception in thread "main" java.lang.IllegalAccessException: Class test can not access a member of class java.util.Vector$1 with modifiers "public"
        at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:57)
        at java.lang.reflect.Method.invoke(Method.java:317)
        at test.main(test.java:46)

Duplicate of bug 4071957.

--   xxxxx@xxxxx   2002-04-24
Comments
  
  Include a link with my name & email   

Submitted On 25-MAY-2000
Bicker
Why this bug (dating from jdk 1.1.3) is not resolved yet?
I reproduced it recently with Linux jdk 1.2.2.

Slawek


Submitted On 26-JUN-2000
wongjava
It appears that invoke is throwing IllegalAccessException 
when invoked on a public method of a non-public class 
inherited by a public class.  You should fix this!


Submitted On 15-FEB-2001
coxcu
I'm still encountering it with JDK 1.3 on Win2K.


Submitted On 06-MAR-2001
BNW
It's really nasty bug! I'm trying to use dynamic proxy 
classes (introduced in JDK1.3) to implement dynamic object 
wrapping and it seems that I cannot invoke a method which 
is visible through an interface but the implementation of 
the interface is not visible to my class e.g. it's an inner 
class...

Please FIX the bug.


Submitted On 01-JUN-2001
jleech
Another fun place you can find this bug is using reflection 
to call methods on a BeanInfo class given to you by 
java.beans.Introspector.getBeanInfo().  The BeanInfo class 
it gives you java.beans.GenericBeanInfo, which is package 
private.  Thanks, Sun.


Submitted On 22-JUN-2001
scheuermann@gmx.de
Well, it is almost 4 years later and neither the documentation nor the code has been fixed. Perhaps a new, shorter, example can help?

The example below results in an IllegalAccessException (JDK 1.2.2 and 1.3)
in the line marked (*). This is rather counterintuitive,
and it does not even seem to agree with the documentation
for Method.invoke().

By the way, the same program runs OK in Visual Age.

package a;
public class Child extends Parent {
}
class Parent {
        public void play() {
        }
}

package b;
import java.lang.reflect.*;
public class Playground {
    public static void main(String[] args) {
        try {
            Class child = a.Child.class;
            Method play = child.getMethod("play", new Class[]{});
            a.Child kid = new a.Child();
            kid.play();
            play.invoke(kid, new Object[]{});
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}



Submitted On 22-JUN-2001
scheuermann@gmx.de
Oops. I forgot to include the (*).
The Exception occurs (of course) when play.invoke() is
invoked.


Submitted On 13-JUL-2001
dipdip
I have reported the same bug in last year too... Without 
progress :-(.

The cause is, that the Reflection has other access rights, 
as the compiled and linked code. F.e. you can not access 
via Reflection a public method in an Anonymous class ( 
coming without scope modifier ==> package scope) from other 
package, but you can access it as compiled code using 
implemented interface.

There are two solutions possible
1) Reflection should have the same access rights to the 
class members as the compiler has. 

2) Reflection should have access rights to the public 
methods of the class with restricted access scope (f.e. 
private) if this method implements the same one in 
interface.


Submitted On 09-AUG-2001
ik1sik
I really need this bug resolved!
Please fix it!!!!


Submitted On 05-NOV-2001
platonoff
This is a very nasty bug indeed! Here's another sample. We 
use generated code, which is wrapped later:

package package1;
class SomeClass_ {
    public String getName() { return "some name"; }
}

package package1;
public class SomeClass extends SomeClass_ {
    public String getSomethingElse() { return null; }
}

import package1.*;
public class AccessTest {
    public static void main( String[] args ) throws 
Exception {
        Object o = new SomeClass();
        System.out.println( "direct: " + ( ( SomeClass ) 
o ).getName() );
        System.out.println( "reflect: " +
            o.getClass().getMethod( "getName", null ).invoke
( o, null ) );
    }
}

The second println (which is accessing the SAME method via 
reflection) fails with IllegalAccessException. The solution 
is to have the generated class "public abstract".


Submitted On 14-DEC-2001
jglick
If I'm not mistaken, this bug affected NetBeans too, it was
necessary to hack around it (catch the exception and retry).


Submitted On 04-FEB-2002
Petr.Pan
Hi, thanks to this bug I've got same problem - in Java 
Applets.
It seems to me that Browsers which uses Java plug-in (like 
Netscape, Mozilla or Opera) calls public methods of java 
Applets through Method.invoke() method.
Here is small example which doesn't work well in browsers 
above.

abstract class Anc {
  public int nonAbstractMethod () { return 0; }
  public int abstractMethod ();
}

public class Desc extends Anc {
  public int abstractMethod { return 1; }
}

If I call nonAbstractMethod() of applet Desc - 
IllegalAccessException is thrown.
Fortunately, I've found simple solution - redefine all 
methods which are inherited from abstract class (and are 
implemented there as well):
public int nonAbstractMethod () { 
  return super.nonAbstractMethod(); 
}

On the other hand, THIS BUG IS MORE THAN 4 YEARS OLD, and 
is not solved yet.
PP


Submitted On 19-MAR-2002
thpreusser
Well, Sun should start thinking about the festivities for
this bug's FIFTH Anniverary! I hope they'll sponsor a free
ticket for all voters voting for bug grandpa.


Submitted On 25-APR-2002
thpreusser
Making this bug a duplicate of 4071957 looks like a bad
joke. Which one is the duplicate if 4071957 was submitted a
day later? Well, I won't complain about making the bug a
little younger - it's just a day. They just don't seem to
like that this bug, which received reasonable attention as
4071593, is still not closed. But instead of solving the
problem, they simply move the whole process to a quiet place
alias 4071957. Certainly, a way to prevent this bug from
ever appearing in the TOP 50 but a crooked one!


Submitted On 25-APR-2002
jleech
everyone needs to change their votes from this bug to
4071957 so that this makes it in the top 25 again.  Every 6 
months or so I come across another way to hit this, and I'm 
always surprised (albeight less and less surprised each 
time) to find that it isn't fixed yet.  This time it was 
trying to iterate over a Set from Perl.


Submitted On 22-MAY-2002
jfoutz
you don't want the method defined by whatever class happens
to implement enum, you want the method declared in the
Enumeration interface...

 Class enumClass = myEnum.getClass();
			// get the class
 Class[] ifaces = enumClass.getInterfaces()
        Method hasMoreElements =

//should really examine every element in the array
//but for example purposes we'll pretend 
//ifaces[0] is Enumeration			ifaces[0].getDeclaredMethod("hasMoreElements",
theArgTypes);

// create the Method from the class& param list



btw: this is not quite the same as 4071957. the private
inner class problem, this is an access subtlety




Submitted On 21-APR-2008
Christoph_W
After 3904 days and getting Java 1.6.0 the bug is still present. The bug does not target inner classes.

package p;
public interface I {
  void someMethod();
}

package p;
abstract class A implements I {
  public final void someMethod() {
    System.out.println("someMethod called");
  }
}

package p;
public final class B extends A {
}

import p.B;
import p.I;
public class Test {
  public static void main(String[] args) throws Exception {
    final I someObject = new B();
    someObject.someMethod();//succeeds
    someObject.getClass().getMethod("someMethod").invoke(someObject);//fails!
  }
}

someMethod called
Exception in thread "main" java.lang.IllegalAccessException: Class Test can not access a member of class p.A with modifiers "public final"
        at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65)
        at java.lang.reflect.Method.invoke(Method.java:588)
        at Test.main(Test.java:7)



PLEASE NOTE: JDK6 is formerly known as Project Mustang