java.lang.IllegalAccessError:尝试从类Entity访问字段ConcreteEntity.instance

时间:2012-12-28 13:22:50

标签: java classloader

  

java.lang.IllegalAccessError:尝试从类Entity访问字段ConcreteEntity.instance

好的,这是交易。我正在尝试访问ConcreteEntity.instance,这是默认ClassLoader内存在访问类型默认的字段,Entity.getInstance是子ClassLoader中存在的方法。

现在请记住,它们都在同一个包中,但是IllegalAccessError被抛出。是否有解决此问题的方法,并不涉及我实际将实体类加载到与ClassLoader相同的ConcreteEntity内?

0 new #14 <Entity>
 3 dup
 4 aload_0
 5 invokevirtual #18 <Adapter.getInstance>
 8 checkcast #20 <sl>
11 getfield #24 <sl.d>
14 invokespecial #25 <Entity.<init>>
17 areturn

通过jclasslib at检索的字节码是“编译后”生成的异常。

感谢Gamb清理帖子。

2 个答案:

答案 0 :(得分:28)

请参阅my answera similar question,除非您的情况很明显,您正在处理多个类加载器:

jvm认为从不同的类加载器加载的类在不同的运行时包&#34;中,即使它们具有相同的包名。引自the jvm spceification,第5.3节:

  

在运行时,类或接口不仅由其名称决定,而是由一对确定:它的完全限定名称及其定义的类加载器。每个这样的类或接口都属于一个运行时包。类或接口的运行时包由包名称和类或接口的类加载器确定。

在第5.4.4节中:

  

当且仅当满足以下任一条件时,才能访问类或接口D的字段或方法R:

     

...

     

R受保护或包私有(即既不公开也不保护也不私有),并且由与相同的运行时包中的类声明。

答案 1 :(得分:1)

Javadoc:通常,编译器会捕获此错误;如果类的定义发生了不兼容的更改,则此错误只能在运行时发生。

由于我认为尝试了一些困难的类操作,也许是类加载,在两个类的加载方式上投入一些时间。 (在极少数情况下,显式的serialVersionId可能有所帮助。)

如果类是相关的(超级/子类),则尝试使用接口删除该关系。可能使用注射。 那不是两次引用/加载一个类。

抱歉,我不能给出具体的答案。