Lorsqu'on tente de sérialiser un objet Java avec un serveur Axis 1.4 (pour un Web Service);
on peut tomber sur l'exception suivante :
13:47:33 WARN AttachmentsImpl: Exception:
AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
faultSubcode:
faultString: java.io.IOException: No serializer found for class java.lang.Class in registry org.apache.axis.encoding.TypeMappingDelegate@16e22da
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}stackTrace:java.io.IOException: No serializer found for class java.lang.Class in registry org.apache.axis.encoding.TypeMappingDelegate@16e22da
at org.apache.axis.encoding.SerializationContext.serializeActual(SerializationContext.java:1507)
at org.apache.axis.encoding.SerializationContext.serialize(SerializationContext.java:980)
at org.apache.axis.encoding.SerializationContext.outputMultiRefs(SerializationContext.java:1055)
at org.apache.axis.message.SOAPBody.outputImpl(SOAPBody.java:145)
at org.apache.axis.message.SOAPEnvelope.outputImpl(SOAPEnvelope.java:478)
at org.apache.axis.message.MessageElement.output(MessageElement.java:1208)
at org.apache.axis.SOAPPart.writeTo(SOAPPart.java:315)
at org.apache.axis.SOAPPart.writeTo(SOAPPart.java:269)
at org.apache.axis.SOAPPart.saveChanges(SOAPPart.java:530)
at org.apache.axis.attachments.AttachmentsImpl.getAttachmentCount(AttachmentsImpl.java:554)
at org.apache.axis.Message.getContentType(Message.java:486)
at org.apache.axis.transport.http.AxisServlet.doPost(AxisServlet.java:775)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
at org.apache.axis.transport.http.AxisServletBase.service(AxisServletBase.java:327)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:172)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:874)
at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)
at java.lang.Thread.run(Thread.java:636)
Une recherche Google sur la phrase exacte "No serializer found for class java.lang.Class" ne donnant qu'un seul résultat peu explicite, je note ici pourquoi j'ai rencontré cette erreur.
Généralement, si c'est une classe ordinaire que le serveur n'a pas réussi à sérialiser, c'est que la définition du type est manquante dans le descripteur de déploiement (fichier .wsdd). Mais ici, l'erreur indique que le serveur n'arrive pas à sérialiser un objet "Class" !
Dans mon cas de figure, l'objet que je tentait de sérialiser comportait une énumération. Et voici, ci dessous comment rédiger un "Custom Serializer" pour une Enum Java :
/**
* Get Custom Serializer
*/
public static org.apache.axis.encoding.Serializer getSerializer(
java.lang.String mechType,
java.lang.Class _javaType,
javax.xml.namespace.QName _xmlType) {
log.debug("getSerializer(...)");
return
new org.apache.axis.encoding.ser.EnumSerializer(_javaType, _xmlType); // , typeDesc);
// new org.apache.axis.encoding.ser.BeanSerializer(_javaType, _xmlType, typeDesc);
}
/**
* Get Custom Deserializer
*/
public static org.apache.axis.encoding.Deserializer getDeserializer(
java.lang.String mechType,
java.lang.Class _javaType,
javax.xml.namespace.QName _xmlType) {
return
new org.apache.axis.encoding.ser.EnumDeserializer(_javaType, _xmlType);
// new org.apache.axis.encoding.ser.BeanDeserializer(_javaType, _xmlType, typeDesc);
}
Vous remarquerez que la ligne en commentaire correspond à un "Serializer" de Classe Java, ici remplacé par un "Serializer" pour une Enum.
Ajout du 15/07/2010 : après avoir reçu ce jour une question sur comment sérialiser un objet comportant un type Enum (JDK 5), j'ai regardé le projet sur lequel j'avais travaillé à l'époque.
Et .. j'étais finalement revenu sur l'utilisation du type Enum : semble-t-il un type trop "spécifique" pour le traitement générique par Axis. J'avais alors remplacé les classes type Enum par des classes simples (donc utilisé au final un BeanSerializer).
Tout çà pour dire que l'exemple cité dans le post ci-dessus n'est certainement pas le mieux choisi (si je reçois un jour la solution, je l'ajouterai..).
Aucun commentaire:
Enregistrer un commentaire