possible bug in java.lang.reflect.Method.invoke(): spurri...

Jamie Stewart (Jamie_Stewart@liebert.com)
Thu, 7 Aug 1997 09:48:55 -0400

Date: Thu, 7 Aug 1997 09:48:55 -0400
From: Jamie_Stewart@liebert.com (Jamie Stewart)
Subject: possible bug in java.lang.reflect.Method.invoke(): spurri...
To: java-security@web2.javasoft.com

Subject: possible bug in java.lang.reflect.Method.invoke(): spurrious
IllegalAccessException

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.invoke(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 behavior that the VM
uses for a regular function invocation.
(End of speculation.)

Sample code is below. This problem is somewhat vexing. I have just submitted it
as a bug, using JavaSoft's bug report CGI page. However, if you can see what I'm
doing wrong here, or can explain why Java is doing the "right thing" here, I'd
be an extremely happy hacker. If there is anything more that I can provide,
please contact me. Thanks.

-Jamie Stewart
Jamie_Stewart@liebert.com

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

}
}

}