I’ve created a simple webapp using Spring & Jetty, and am creating a hello world JDO test using DataNucleus & DB4O.
I can persist a class no problem, but when I go to query for the class I get a ClassCastException, can’t cast a.b.c.MyClass to a.b.c.MyClass.
When I examine the classloader of the original object I created, it’s [WebAppClassLoader@1592226291], naturally it’s springs WebApp classloader.
I am performing both the persist operation and query operation in the same servlet method, when I re-read the object from the DB with a simple query I get back a set of a.b.c.MyClass objects from the DB, but the classloader is [sun.misc.Launcher$AppClassLoader@5acac268], thus the exception.
Following the DataNucleus docs here http://www.datanucleus.org/extensions/classloader_resolver.html
…the JDO2 class-loading mechanism
utilises 3 class loaders
* When creating the PersistenceManagerFactory you can
specify a class loader. This is used
first if specified
* The second class loader to try is the class loader for the current
thread.
* The third class loader to try is the class loader for the PMF context.
I covered the first two options documented, and verified that the classloader is the WebAppClassLoader in the Servlet with these debug steps in the servlet:
Thread.currentThread().getContextClassLoader().toString()
((JDOPersistenceManagerFactory)pm.getPersistenceManagerFactory()).getPrimaryClassLoader().toString()
Both yield [WebAppClassLoader@1592226291] as the classloader.
I’m not sure where I’m going wrong here.
My earlier comment as an answer:
This exception indicates that it is a class loader issue. Compare the class-loader of the object and the class you’re using for the cast.
Btw: If db4o is using the wrong class-loader. You can change that by configuring the class-loader explicit.
When a single class-loader isn’t enough: You can also pass a instance of the db4o-interface JdkLoader instead of a class-loader. In there you can implement any class-lookup method. For example to look up in multiple class loaders.