ClassCastException in DAO DataNucleus object when saving / retrieving an object using JDO

I created a simple webapp using Spring and Jetty, and am creating a JDO welcome test in the world using DataNucleus and DB4O.

I can save the class without problems, but when I go to the request for the class, I get a ClassCastException , I can not distinguish abcMyClass from abcMyClass .

When I examine the class loader of the source object that I created, it [ WebAppClassLoader@1592226291 ] , naturally, it launches the WebApp class loader.

I perform the continue and query operation in the same servlet method, when I re-read an object from the database with a simple query, I return a set of abcMyClass objects from the database, but the class loader [ sun.misc.Launcher$AppClassLoader@5acac268 ] is thus an exception.

Following the DataNucleus docs here http://www.datanucleus.org/extensions/classloader_resolver.html

... JDO2 class loading mechanism uses 3 classes of loaders
* When creating a PersistenceManagerFactory, you can specify the class loader. This is used first if | * The second class loader to load is the class loader for the current thread.
* The third class tracker to try is the class loader for the PMF context.

I reviewed the first two parameters described and confirmed that classloader is WebAppClassLoader in Servlet with these debugging steps in the servlet:

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

Both give [ WebAppClassLoader@1592226291 ] as the class loader.

I am not sure where I am going wrong.

+4
source share
1 answer

My previous comment as an answer:

This exception indicates that this is a class loader issue. Compare the object loader class with the class you use for translation.

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

Btw: If db4o uses the wrong classloader. You can change this by configuring the kernel of the loader class.

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

If one bootloader class is not enough: you can also pass an instance of the db4o JdkLoader interface instead of the bootloader class. There you can implement any class search method. For example, to search multiple classloaders.

+1
source

All Articles