什么时候使用ClassDefiner?
我遇到了一个 ClassLoader 问题,它是这样的:
java.lang.ClassCastException: com.google.appengine.api.datastore.Key
cannot be cast to com.google.appengine.api.datastore.Key
起初我不知道这是怎么发生的,但经过一番搜索后我了解到,如果同一个类也可以抛出 ClassCastException
由 2 个不同的 ClassLoader 加载。我继续挖掘并发现了这一点:
[从 JVM_DefineClass 加载了 com.google.appengine.api.datastore.Key]
...
[已从文件加载 com.google.appengine.api.datastore.Key:/home/alex/java/eclipse/plugins/com.google.appengine.eclipse.sdkbundle_1.5.1.r36v201106211634/appengine-java-sdk-1.5.1 /lib/user/appengine-api-1.0-sdk-1.5.1.jar]
这确实是证明该Key
实际上是在2个不同的ClassLoader
中加载的。然而,我不知道如何继续我的调查;我知道一个新的 ClassLoader
是通过 ClassDefiner
实例化的(参见 http://www.java2s.com/Open-Source/Java-Document/6.0-JDK-Modules-sun/reflect/sun/reflect/ClassDefiner.java.htm),但是我不知道为什么。我用谷歌搜索了一些答案,但没有找到。
它与基础测试使用 @BeforeClass 设置不同的 ClassLoader 的事实有什么关系吗?但如果这是真的(我可以接受 JVM_DefineClass),那么第二个 ClassLoader 是做什么用的?
希望能在这里找到一些答案 亚历克斯.
I've run into a ClassLoader problem, and it goes something like this:
java.lang.ClassCastException: com.google.appengine.api.datastore.Key
cannot be cast to com.google.appengine.api.datastore.Key
At first I had no idea how this could happen, but after some search I learned that ClassCastException
can also be thrown if the same class is loaded by 2 different ClassLoader
s. I continued to dig around and discovered this:
[Loaded com.google.appengine.api.datastore.Key from JVM_DefineClass]
...
[Loaded com.google.appengine.api.datastore.Key from file:/home/alex/java/eclipse/plugins/com.google.appengine.eclipse.sdkbundle_1.5.1.r36v201106211634/appengine-java-sdk-1.5.1/lib/user/appengine-api-1.0-sdk-1.5.1.jar]
This is indeed the proof that Key
is actually loaded in 2 different ClassLoader
s. However, I have no idea how to continue my investigation; I know a new ClassLoader
is instantiated via ClassDefiner
(see http://www.java2s.com/Open-Source/Java-Document/6.0-JDK-Modules-sun/reflect/sun/reflect/ClassDefiner.java.htm), but I have no idea why. I've googled for some answers, but found none.
Does it have anything to do with the fact that a base test sets a different ClassLoader
using @BeforeClass
? But if that's true (I can accept JVM_DefineClass), what is the second ClassLoader
all about?
Hope to find some answers here,
Alex.
我不确定我完全理解你的问题,但没有其他人回答,所以我会尝试一下。首先,ClassDefiner 与此有什么关系?你在某处使用它吗?即使 ClassDefiner 创建了一个新的 ClassLoader,它也会使用给定的父 ClassLoader 作为新 ClassLoader 的父级,并且默认的 ClassLoader 行为是在加载它自己之前在父 ClassLoader 中搜索类,因此这本身不会导致“类”由两个类加载器加载”您所描述的问题。
在 @BeforeClass 中设置不同的 ClassLoader 是什么意思?如果你在某个ClassLoader中加载一个类,将类或类的实例保留在某个地方,然后任意切换ClassLoader,你肯定会看到这样的问题。
这些有帮助吗?我感觉您正在寻找 Java 核心类中的错误,而您可能应该查看自己的代码。始终谨慎假设已建立的库中存在错误。
I'm not sure I quite grasp your problem, but nobody else is answering, so I'll give it a shot. First, what does ClassDefiner have to do with this? Are you using it somewhere? Even though ClassDefiner creates a new ClassLoader, it uses the given parent ClassLoader as the new ClassLoader's parent, and default ClassLoader behavior is to search for a class in a parent ClassLoader before loading it itself, so this by itself won't cause the "class is loaded by two ClassLoaders" problem that you're describing.
What do you mean about setting a different ClassLoader in @BeforeClass? If you load a class in some ClassLoader, keep the class or instances of the class around somewhere, and then arbitrarily switch ClassLoaders, you could certainly see problems like this.
Does any of that help? I get the feeling you're looking for a bug in the Java core classes when you should probably be looking at your own code. Always be cautious to assume a bug in an established library.