您的位置:首页 > 编程语言 > Java开发

IllegalAccessException: Class A can not access a member of class B 的一种原因分析与解决

2016-12-24 12:30 549 查看

Caused by: java.lang.IllegalAccessException: Class A can not access a member of class B 的一种原因分析与解决

我在使用到一个java fluent api工具时遇到这个问题,出现异常后调用栈如下。

Caused by: java.lang.IllegalAccessException: Class com.fluentinterface.proxy.BuilderProxy can not access a member of class zk.curator.Person with modifiers "public"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:296)
at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:288)
at java.lang.reflect.Constructor.newInstance(Constructor.java:413)
at com.fluentinterface.proxy.BuilderProxy.createInstanceFromProperties(BuilderProxy.java:79)
at com.fluentinterface.proxy.BuilderProxy.invoke(BuilderProxy.java:56)


最后抛出了IllegalAccessException异常,这个异常的定义如下。

An IllegalAccessException is thrown when an application tries to reflectively create an instance (other than an array),

set or get a field, or invoke a method, but the currently executing method does not have access to the definition of the specified class,

field, method or constructor.

从异常定义可以看出,由于通过反射的机制创建实例,由于没有权限访问类,域,方法构造器而产生该异常。

通过抛出的异常可以看出,在调用sun.reflect.Reflection.ensureMemberAccess检查访问权限时抛出异常。

if (!verifyMemberAccess(currentClass, memberClass, target, modifiers)) {
throw new IllegalAccessException("Class " + currentClass.getName() +
" can not access a member of class " +
memberClass.getName() +
" with modifiers \"" +
Modifier.toString(modifiers) +
"\"");
}


该方法内部由于调用verifyMemberAccess,且未满足条件时抛出了异常。

public static boolean  verifyMemberAccess(Class currentClass,
// Declaring class of field
// or method
Class  memberClass,
// May be NULL in case of statics
Object target,
int    modifiers)
{
// Verify that currentClass can access a field, method, or
// constructor of memberClass, where that member's access bits are
// "modifiers".

boolean gotIsSameClassPackage = false;
boolean isSameClassPackage = false;

if (currentClass == memberClass) {
// Always succeeds
return true;
}

if (!Modifier.isPublic(getClassAccessFlags(memberClass))) {
isSameClassPackage = isSameClassPackage(currentClass, memberClass);
gotIsSameClassPackage = true;
if (!isSameClassPackage) {
return false;
}

......略
}


可以看到verifyMemberAccess会检查所创建的类是访问描述符是否是public,若不是public,那么检查所创建的类与调用类是否在同一个包下,如果不在同一个包下则返回false。而我在练习使用fluent api 工具时,所定义的类XXX为并不是public,而且和工具类不在一个包下,因此导致IllegalAccessException异常的产生。

class XXX{

}


最后将类修改为public问题解决。可以想到,做这样的检查是为了确保对目标类有权限访问。

参考:

[1] sun.reflect.* 源码, http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b27/sun/reflect/Reflection.java#Reflection.verifyMemberAccess%28java.lang.Class%2Cjava.lang.Class%2Cjava.lang.Object%2Cint%29
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 异常 class
相关文章推荐