-
Bug
-
Resolution: Fixed
-
P4
-
7
-
b22
-
x86
-
windows_vista
FULL PRODUCT VERSION :
java version "1.7.0"
Java(TM) SE Runtime Environment (build 1.7.0-b147)
Java HotSpot(TM) 64-Bit Server VM (build 21.0-b17, mixed mode)
A DESCRIPTION OF THE PROBLEM :
A bean inherits public isX() method for a boolean property from a package-private base class. The java.beans.Introspector returns the property descriptor for the X property. But when its read method is invoked from outside the bean package there is a java.lang.IllegalAccessException.
The problem is not observed for inherited getX() properties neither when the base class is public.
The isX() read method returned by the Introspector has its declared class set to the base class not to the bean class itself. For inherited getX() properties the declared class of the reader method is the bean class. If the isX() method is retrieved with reflection its declared class is the bean class.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1) Add the bean and its base class in a "bean" package, the Test class in the default package.
2) Run Test class.
ACTUAL -
m1.getDeclaringClass(): "class bean.Derived"
Invocation result:true
m1.equals(m2)=false
m2.getDeclaringClass(): "class bean.Base"
java.lang.IllegalAccessException: Class Test can not access a member of class be
an.Base with modifiers "public"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:95)
at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:261)
at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:253)
at java.lang.reflect.Method.invoke(Method.java:594)
at Test.testDerivedIsBooleanProp(Test.java:48)
at Test.main(Test.java:20)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
-----
package bean;
public class Derived extends Base {
}
-----
package bean;
/* package */ class Base {
public boolean isAllowed() {
return true;
}
}
-----
import java.beans.*;
import java.lang.reflect.*;
import java.util.*;
import bean.Derived;
public class Test {
public static void main(String[] args) {
try {
testDerivedIsBooleanProp();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void testDerivedIsBooleanProp() throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, IntrospectionException {
Derived bean = new Derived();
Class<?> type = bean.getClass();
// Use reflection
Method m1 = type.getMethod("isAllowed");
System.out.println("m1.getDeclaringClass(): " + " \"" + m1.getDeclaringClass() + "\"");
System.out.println("Invocation result:" + m1.invoke(bean));
// Use bean introspection
Map<String, PropertyDescriptor> properties = new HashMap<String, PropertyDescriptor>();
BeanInfo info = Introspector.getBeanInfo(type);
PropertyDescriptor[] pds = info.getPropertyDescriptors();
for (int i = 0; i < pds.length; i++) {
properties.put(pds[i].getName(), pds[i]);
}
PropertyDescriptor propDesc = properties.get("allowed");
Method m2 = propDesc.getReadMethod();
System.out.println("m1.equals(m2)=" + m1.equals(m2));
System.out.println("m2.getDeclaringClass(): " + " \"" + m2.getDeclaringClass() + "\"");
System.out.println("Invocation result:" + m2.invoke(bean, (Object[]) null));
}
}
---------- END SOURCE ----------
java version "1.7.0"
Java(TM) SE Runtime Environment (build 1.7.0-b147)
Java HotSpot(TM) 64-Bit Server VM (build 21.0-b17, mixed mode)
A DESCRIPTION OF THE PROBLEM :
A bean inherits public isX() method for a boolean property from a package-private base class. The java.beans.Introspector returns the property descriptor for the X property. But when its read method is invoked from outside the bean package there is a java.lang.IllegalAccessException.
The problem is not observed for inherited getX() properties neither when the base class is public.
The isX() read method returned by the Introspector has its declared class set to the base class not to the bean class itself. For inherited getX() properties the declared class of the reader method is the bean class. If the isX() method is retrieved with reflection its declared class is the bean class.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1) Add the bean and its base class in a "bean" package, the Test class in the default package.
2) Run Test class.
ACTUAL -
m1.getDeclaringClass(): "class bean.Derived"
Invocation result:true
m1.equals(m2)=false
m2.getDeclaringClass(): "class bean.Base"
java.lang.IllegalAccessException: Class Test can not access a member of class be
an.Base with modifiers "public"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:95)
at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:261)
at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:253)
at java.lang.reflect.Method.invoke(Method.java:594)
at Test.testDerivedIsBooleanProp(Test.java:48)
at Test.main(Test.java:20)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
-----
package bean;
public class Derived extends Base {
}
-----
package bean;
/* package */ class Base {
public boolean isAllowed() {
return true;
}
}
-----
import java.beans.*;
import java.lang.reflect.*;
import java.util.*;
import bean.Derived;
public class Test {
public static void main(String[] args) {
try {
testDerivedIsBooleanProp();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void testDerivedIsBooleanProp() throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, IntrospectionException {
Derived bean = new Derived();
Class<?> type = bean.getClass();
// Use reflection
Method m1 = type.getMethod("isAllowed");
System.out.println("m1.getDeclaringClass(): " + " \"" + m1.getDeclaringClass() + "\"");
System.out.println("Invocation result:" + m1.invoke(bean));
// Use bean introspection
Map<String, PropertyDescriptor> properties = new HashMap<String, PropertyDescriptor>();
BeanInfo info = Introspector.getBeanInfo(type);
PropertyDescriptor[] pds = info.getPropertyDescriptors();
for (int i = 0; i < pds.length; i++) {
properties.put(pds[i].getName(), pds[i]);
}
PropertyDescriptor propDesc = properties.get("allowed");
Method m2 = propDesc.getReadMethod();
System.out.println("m1.equals(m2)=" + m1.equals(m2));
System.out.println("m2.getDeclaringClass(): " + " \"" + m2.getDeclaringClass() + "\"");
System.out.println("Invocation result:" + m2.invoke(bean, (Object[]) null));
}
}
---------- END SOURCE ----------