java.lang.IllegalAccessError: 试图从类实体访问字段 ConcreteEntity.instance
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14070215/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
java.lang.IllegalAccessError: tried to access field ConcreteEntity.instance from class Entity
提问by Justin
java.lang.IllegalAccessError: tried to access field ConcreteEntity.instance from class Entity
java.lang.IllegalAccessError: 试图从类实体访问字段 ConcreteEntity.instance
Ok so here is the deal. I am trying to access ConcreteEntity.instance
which is a field with the access type default that exists inside the default ClassLoader
and the Entity.getInstance
is a method that exist in a child ClassLoader
.
好的,这是交易。我正在尝试访问ConcreteEntity.instance
which 是一个字段,其访问类型 default 存在于 default 中ClassLoader
,而Entity.getInstance
is 是存在于 child 中的方法ClassLoader
。
Now keep in mind they're both in the same package, however an IllegalAccessError
is being thrown. Is there a solution to this problem that doesn't involve me actually loading the Entity class inside the same ClassLoader
as ConcreteEntity
?
现在请记住,它们都在同一个包中,但是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
The bytecode retrieved via jclasslib at were the exception is generated "After being compiled".
通过 jclasslib 检索的字节码在“编译后”生成异常时。
Thank you Gamb for cleaning up the post.
感谢 Gamb 清理帖子。
回答by J?rn Horstmann
See my answerto a similar question, except in your case it is clear that you are dealing with multiple classloaders:
请参阅我对类似问题的回答,除非在您的情况下很明显您正在处理多个类加载器:
The jvm considers classes loaded from different classloaders to be in different "runtime packages", even if they have the same package name. Quoting from the jvm spceification, section 5.3:
jvm 认为从不同的类加载器加载的类位于不同的“运行时包”中,即使它们具有相同的包名。引用jvm spceification,第 5.3 节:
At run time, a class or interface is determined not by its name alone, but by a pair: its fully qualified name and its defining class loader. Each such class or interface belongs to a single runtime package. The runtime package of a class or interface is determined by the package name and defining class loader of the class or interface.
在运行时,一个类或接口不仅仅由它的名称决定,而是由一对决定:它的完全限定名称和它的定义类加载器。每个这样的类或接口都属于一个运行时包。类或接口的运行时包由包名称和类或接口的定义类加载器决定。
And in section 5.4.4:
在第 5.4.4 节中:
A field or method R is accessible to a class or interface D if and only if any of the following conditions is true:
...
R is either protected or package private (that is, neither public nor protected nor private), and is declared by a class in the same runtime packageas D.
当且仅当满足以下任一条件时,类或接口 D 可以访问字段或方法 R:
...
R 要么是受保护的,要么是包私有的(即既不是公共的,也不是受保护的,也不是私有的),并且由与 D相同的运行时包中的类声明。
回答by Joop Eggen
Javadoc:Normally, this error is caught by the compiler; this error can only occur at run time if the definition of a class has incompatibly changed.
Javadoc:正常情况下,这个错误是被编译器捕捉到的;如果类的定义发生了不兼容的更改,则此错误只会在运行时发生。
As I think that some difficult class manipulation is attempted, maybe class loading, invest some time in how both classes are loaded. (In rare cases an explicit serialVersionId might help.)
因为我认为尝试了一些困难的类操作,也许是类加载,请在这两个类的加载方式上投入一些时间。(在极少数情况下,明确的 serialVersionId 可能会有所帮助。)
If the classes are related (super / subclass), then try to remove that relation using an interface. Possibly use injection. That is not refer/load a class twice.
如果类是相关的(超/子类),则尝试使用接口删除该关系。可能使用注射。这不是两次引用/加载一个类。
Sorry a concrete answer I cannot give.
抱歉,我无法给出具体的答案。