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

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值