"IOP00810257: (MARSHAL) Could not load class

Architectures Logicielles Java(2)

Modérateurs : graffiop, jmdouin, agoncal, mlebihan

hhf
Messages : 56
Inscription : 24 oct. 2008 19:49

"IOP00810257: (MARSHAL) Could not load class

Message par hhf » 03 sept. 2009 22:24

Je profite du rétablissement du Forum, pour poser une question dont je ne trouve pas la solution sur le net.

Donc voila, lors de la récupération d'une Collection<SpokenLanguage> sur l'appel d'un EJB Stateless avec comme argument cette collection, j'ai l'erreur suivante, comme quoi le serveur EJB ne trouve pas la classe SpokenLanguage.
Je suis sous Glassfish, en mode un war et un jar.
C'est Glassfish 2.1
Avec netbean 6.7.1
Le JDK est identique pour les 2 projets war et ejb.

Voici les essais que j'ai effectuer pour m'aider à y voir plus clair :
- Si je change le serialUNID, l'erreur persiste.
- Si je supprime le serialUNID, l'erreur persiste.

- Si je transforme ma Collection en un simple Field avec les getter setter adéquats :
private Collection<SpokenLanguage> list; => private SpokenLanguage spokenLanguage
l'erreur disparait.

- Si je deploy l'application dans un ear plutôt qu'un war et jar separé,, l'erreur disparait.

Voila, si quelqu'un à une idée, je suis preneur, car la solution de déployer le ear plutôt que le jar+war est plus lourde je trouve.

A noter aussi que les autres Collections sérialisées ne posent aucun problème.

Voici la trace :


"IOP00810257: (MARSHAL) Could not load class hhf.helloworld.common.entity.criteria.SpokenLanguage"
org.omg.CORBA.MARSHAL: vmcid: SUN minor code: 257 completed: Maybe
at com.sun.corba.ee.impl.logging.ORBUtilSystemException.couldNotFindClass(ORBUtilSystemException.java:9679)
at com.sun.corba.ee.impl.logging.ORBUtilSystemException.couldNotFindClass(ORBUtilSystemException.java:9694)
at com.sun.corba.ee.impl.encoding.CDRInputStream_1_0.read_value(CDRInputStream_1_0.java:1042)
at com.sun.corba.ee.impl.encoding.CDRInputStream_1_0.read_value(CDRInputStream_1_0.java:896)
at com.sun.corba.ee.impl.encoding.CDRInputStream_1_0.read_abstract_interface(CDRInputStream_1_0.java:890)
at com.sun.corba.ee.impl.encoding.CDRInputStream_1_0.read_abstract_interface(CDRInputStream_1_0.java:880)
at com.sun.corba.ee.impl.encoding.CDRInputStream.read_abstract_interface(CDRInputStream.java:511)
at com.sun.corba.ee.impl.io.IIOPInputStream.readObjectDelegate(IIOPInputStream.java:386)
at com.sun.corba.ee.impl.io.IIOPInputStream.readObjectOverride(IIOPInputStream.java:547)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:345)
at java.util.ArrayList.readObject(ArrayList.java:593)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.corba.ee.impl.io.IIOPInputStream.invokeObjectReader(IIOPInputStream.java:1688)
at com.sun.corba.ee.impl.io.IIOPInputStream.inputObject(IIOPInputStream.java:1211)
at com.sun.corba.ee.impl.io.IIOPInputStream.simpleReadObject(IIOPInputStream.java:422)
at com.sun.corba.ee.impl.io.ValueHandlerImpl.readValueInternal(ValueHandlerImpl.java:362)
at com.sun.corba.ee.impl.io.ValueHandlerImpl.readValue(ValueHandlerImpl.java:328)
at com.sun.corba.ee.impl.encoding.CDRInputStream_1_0.readRMIIIOPValueType(CDRInputStream_1_0.java:966)
at com.sun.corba.ee.impl.encoding.CDRInputStream_1_0.read_value(CDRInputStream_1_0.java:1052)
at com.sun.corba.ee.impl.encoding.CDRInputStream.read_value(CDRInputStream.java:475)
at com.sun.corba.ee.impl.io.IIOPInputStream.inputObjectField(IIOPInputStream.java:1983)
at com.sun.corba.ee.impl.io.IIOPInputStream.inputClassFields(IIOPInputStream.java:2208)
at com.sun.corba.ee.impl.io.IIOPInputStream.inputObject(IIOPInputStream.java:1220)
at com.sun.corba.ee.impl.io.IIOPInputStream.simpleReadObject(IIOPInputStream.java:422)
at com.sun.corba.ee.impl.io.ValueHandlerImpl.readValueInternal(ValueHandlerImpl.java:362)
at com.sun.corba.ee.impl.io.ValueHandlerImpl.readValue(ValueHandlerImpl.java:328)
at com.sun.corba.ee.impl.encoding.CDRInputStream_1_0.readRMIIIOPValueType(CDRInputStream_1_0.java:966)
at com.sun.corba.ee.impl.encoding.CDRInputStream_1_0.read_value(CDRInputStream_1_0.java:1052)
at com.sun.corba.ee.impl.encoding.CDRInputStream.read_value(CDRInputStream.java:475)
at com.sun.corba.ee.impl.presentation.rmi.DynamicMethodMarshallerImpl$14.read(DynamicMethodMarshallerImpl.java:368)
at com.sun.corba.ee.impl.presentation.rmi.DynamicMethodMarshallerImpl.readArguments(DynamicMethodMarshallerImpl.java:435)
at com.sun.corba.ee.impl.presentation.rmi.ReflectiveTie._invoke(ReflectiveTie.java:152)
at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatchToServant(CorbaServerRequestDispatcherImpl.java:687)
at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(CorbaServerRequestDispatcherImpl.java:227)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequestRequest(CorbaMessageMediatorImpl.java:1846)
at com.sun.corba.ee.impl.protocol.SharedCDRClientRequestDispatcherImpl.marshalingComplete(SharedCDRClientRequestDispatcherImpl.java:183)
at com.sun.corba.ee.impl.protocol.CorbaClientDelegateImpl.invoke(CorbaClientDelegateImpl.java:219)
at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.privateInvoke(StubInvocationHandlerImpl.java:192)
at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.invoke(StubInvocationHandlerImpl.java:152)
at com.sun.corba.ee.impl.presentation.rmi.bcel.BCELStubBase.invoke(BCELStubBase.java:225)

mlebihan
Messages : 114
Inscription : 09 févr. 2007 1:03

Re: "IOP00810257: (MARSHAL) Could not load class

Message par mlebihan » 06 sept. 2009 21:24

Bonjour,

Bien que ne pouvant investiguer le problème en profondeur, la plupart des problèmes qui tournent autour des classes non trouvées ou de mauvaise version sont souvent dues à des duplications de classes dans des distributions séparées.
Cela produit souvent des erreurs de type Invalid Serial Version et pourrait générer celle-ci.

Dans le monde Java, on peut trouver jusqu'à quatre conteneurs distincts, c'est à dire qu'ils ont chacun leurs propre Classloader.
- Applet.
- Serveur d'application.
- Web.
- "Classique": Ligne de commande.

Ce qui se passe si une classe se trouve à la fois dans un jar et dans un war, c'est qu'elle sera lue avec un serial ID donné d'un côté (war = conteneur web), et un autre de l'autre (jar = ressource serveur d'application).
Bien que l'affectation d'un serialUID soit supposé régler le problème, je me suis rendu compte (sous JBoss) que c'était loin d'être le cas, et que deux classes venues de Classloaders distincts créaient bien souvent des problèmes.

Par la suite, je me suis toujours assuré qu'une classe n'existe qu'à un seul endroit. Si elle doit être partagée entre couches logicielles, elle n'existera que dans un jar, en un unique exemplaire. Et ce jar, également, ne sera présent qu'en un seul exemplaire dans JBoss ou Glassfish.

Cordialement,

Marc Le Bihan.

hhf
Messages : 56
Inscription : 24 oct. 2008 19:49

Re: "IOP00810257: (MARSHAL) Could not load class

Message par hhf » 07 sept. 2009 15:38

Effectivement ce que vous decrivez correspond à mes symptomes.
Quand je deploie via un seul ear, et non plus un jar contenant les entités et un war les contenant aussi, le probleme disparait.

Néanmoins, si la solution existe, elle remet pas mal en cause l'architecture distribué, si je peux pas créer une application tierce qui exploitera mes ejbs et leurs entités respectifs, je vois plus trop l'intérêt.
Forcement si distribué il y a forcement il y aura des '.class' qui vont être en double, en tous cas au niveaux du file system. après dans la JVM, elle devrait voir (ce qu'elle fait pour toutes mes autres classes) que c'est les même classes.

Cordialement

hhf
Messages : 56
Inscription : 24 oct. 2008 19:49

Re: "IOP00810257: (MARSHAL) Could not load class

Message par hhf » 10 sept. 2009 12:43

Petite avancé dans ce probleme, qui reste sans réelle explication.

je re-situe le contexte,
j'utilise glassfish, en mode deux conteneurs, un web et un EJB (war, jar).
j'ai une entité Profile avec une List de SpokenLanguage
quand j'appelle un ejb avec comme argument un profile, le conteneur EJB me remonte une exception comme quoi il trouve pas la classe SpokenLanguage

Seule solution trouvé jusque la, mettre tout dans un ear et donc un seul ClassLoader. Mais le déploiement de cette solution en tous cas durant le développement et un peu plus lourd, donc j'ai cherché une autre solution.

j'avais déjà essayé de ne passé qu'un seul SpokenLanguage en créant un field sur l'entité Profil, cela marché. Donc le ClassLoader trouvait bien la classe.
J'ai donc essayé en modifiant la méthode de l'EJB

j'ai changé la signature de

Code : Tout sélectionner

void updateProfile(Profile p);
en

Code : Tout sélectionner

void updateProfile(Profile p, List<SpokenLanguage> list);
Mais... le probleme persiste
autre essai avec

Code : Tout sélectionner

void updateProfile(Profile p, SpokenLanguage[] list);
Et la miracle ca marche.
Bon effectivement je dois faire un petite manipulation du coté de la classe coté WEB, mais la liste n'est jamais longue donc, pas de soucie.

Voila, c'est pas super super satisfaisant, ca dit pas pourquoi ca marche, mais si vous rencontrez ce genre de problème, testez ceci.

Répondre