2010-10-25 98 views
4

J'ai créé une application Web simple à l'aide de Spring & Jetty et je crée un test JDO de Hello World à l'aide de DataNucleus & DB4O.ClassCastException dans l'objet DAO DataNucleus lors de la persistance/récupération d'un objet à l'aide de JDO

Je peux persister un problème de classe pas, mais quand je vais à la requête pour la classe je reçois un ClassCastException, ne peut pas lancer a.b.c.MyClass à a.b.c.MyClass.

Lorsque j'examine le chargeur de classe de l'objet d'origine que j'ai créé, il s'agit de [[email protected]], il s'agit naturellement du chargeur de classe WebApp.

J'effectue à la fois l'opération de persistance et l'opération de requête dans la même méthode de servlet, lorsque je relis l'objet de la base de données avec une requête simple, je récupère un ensemble d'objets abcMyClass de la base de données. est [[email protected]], donc l'exception.

Après les docs DataNucleus ici http://www.datanucleus.org/extensions/classloader_resolver.html

... le mécanisme de chargement de classe JDO2 utilise 3 chargeurs de classes
* Lors de la création du PersistenceManagerFactory vous pouvez spécifier un chargeur de classe. Ceci est utilisé d'abord si spécifié
* Le chargeur de deuxième classe à essayer est le chargeur de classe pour le thread actuel.
* Le chargeur de troisième classe à essayer est le chargeur de classe pour le contexte PMF.

Je couvert les deux premières options documentées, et vérifié que le classloader est le WebAppClassLoader dans le Servlet avec ces étapes de débogage dans le servlet:

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

fois le rendement [[email protected]] comme classloader.

Je ne sais pas où je vais me tromper ici.

+0

Avez-vous vérifié les chargeurs de classes de l'objet et de la classe dans la distribution? object.getClass(). getClassLoader(). est égal à (MyClass.class.getClassLoader())? Une telle exception est 99% un problème de chargeur de classe. – Gamlor

+0

Je pense que je le vois maintenant. C'est un problème Jetty/Spring, Spring me permet de définir des composants sous le contexte de l'application (loader de la classe système) et d'autres dans les contextes de servlet (loader de classes d'application web fourni par jetty). Vous devriez publier cela comme une réponse. –

Répondre

1

Mon commentaire précédent comme une réponse:

Cette exception indique qu'il est un problème de chargeur de classe. Comparez le chargeur de classe de l'objet et la classe que vous utilisez pour la distribution.

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

Btw: Si db4o utilise un mauvais chargeur de classe. Vous pouvez changer cela en configurant le class-loader explicite.

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

Lorsqu'un seul chargeur de classe ne suffit pas: Vous pouvez également passer une instance de l'interface db4o JdkLoader au lieu d'un chargeur de classe. Là, vous pouvez implémenter n'importe quelle méthode de recherche de classe. Par exemple pour rechercher dans plusieurs chargeurs de classe.