2010-10-25 60 views
4

我已经使用Spring创建了一个简单的webapp & Jetty,并且正在使用DataNucleus创建一个hello world JDO测试& DB4O。使用JDO持久/检索对象时DataNucleus DAO对象中的ClassCastException

我可以坚持班级没问题,但是当我去查询班级时我得到ClassCastException,不能投a.b.c.MyClassa.b.c.MyClass

当我检查我创建的原始对象的类加载器时,它是[[email protected]],它自然是弹出WebApp类加载器。

我在同一个servlet方法中执行持久操作和查询操作时,当我用DB从一个简单的查询中重新读取对象时,我从DB获取一组abcMyClass对象,但是类加载器是[[email protected]],因此是例外。

继DataNucleus将文档这里http://www.datanucleus.org/extensions/classloader_resolver.html

...的JDO2类加载机制 利用3类加载器
*当创建一个PersistenceManagerFactory,你可以 指定一个类加载器。如果指定,则首先使用
*要尝试的第二个类加载器是当前的 线程的类加载器。
*要尝试的第三个类加载器是PMF上下文的类加载器。

我介绍介绍的前两个选项,并验证类加载器与在servlet这些调试步骤了Servlet的WebAppClassLoader

Thread.currentThread().getContextClassLoader().toString() 
((JDOPersistenceManagerFactory)pm.getPersistenceManagerFactory()).getPrimaryClassLoader().toString() 

两个产生[[email protected]]的类加载器。

我不知道我在哪里错了。

+0

你是否检查过对象的类加载器和类中的类? object.getClass()。getClassLoader()。等于(MyClass.class.getClassLoader())?这样的例外是99%的类加载器问题。 – Gamlor 2010-10-25 14:31:17

+0

我想我现在看到它了。这是一个Jetty/Spring问题,Spring允许我在应用程序上下文(系统类加载器)和servlet上下文(jetty提供的Web应用程序类加载器)中定义一些组件。您应该将其作为答案发布。 – 2010-10-25 14:56:29

回答

1

我作为一个答案先前的评论:

此异常指示它是一个类加载器的问题。比较对象的类加载器和您用于演员的类。

ClassLoader loaderOfObject = theObject.getClass().getClassLoader(); 
ClassLoader loaderOfLocalClass = MyClass.getClassLoader(); 
// have to be the same. 
assert loaderOfObject.equals(loaderOfLocalClass); 

btw:如果db4o使用错误的类加载器。你可以通过显式配置类加载器来改变它。

EmbeddedConfiguration configuration = Db4oEmbedded.newConfiguration(); 
    JdkReflector reflector = new JdkReflector(Thread.currentThread().getContextClassLoader()); 
    configuration.common().reflectWith(reflector); 
    ObjectContainer container = Db4oEmbedded.openFile(configuration, "database.db4o"); 

当一个类加载器是不够的:您也可以通过JdkLoader,而不是一个类加载器db4o的接口的实例。在那里你可以实现任何类查找方法。例如查找多个类加载器。