Metro sur WebSphere 7 - exception incompatible avec com.ibm.xml.xlxp2.jaxb.JAXBContextImpl

Problème

Développement d’un service Web SOAP via Metro 2.0.1 ( webservices-rt.jar ), intégration avec Spring via` jaxws-spring-1.8.jar` et déploiement sur WebSphere Application Server (WAS) version 7.0 .0.13. Voir le service Web ci-dessous:

File: UserWS.java

package com.mkyong.user.ws;//import...
@WebService()
public class UserWS {

    private UserBo userBo;

    @WebMethod(exclude = true)
    public UserBo getUserBo() {
        return userBo;
    }

    @WebMethod(exclude = true)
    public void setUserBo(UserBo userBo) {
        this.userBo = userBo;
    }

    @WebMethod(operationName = "listUser")
    public List<User> listUser() throws SOAPException {

       return userBo.listUser();

    }
}

Si tout va bien, le service fonctionne comme prévu, mais lorsque “` userBo.listUser () ” frappe une erreur et renvoie une `SOAPException au client du service Web:

Le client obtient ceci:

Exception in thread "main"
    javax.xml.ws.WebServiceException: No Content-type in the header!

Fichier journal WAS indiquant ceci:

Caused by: java.lang.ClassCastException: com.ibm.xml.xlxp2.jaxb.JAXBContextImpl
    incompatible with com.sun.xml.bind.api.JAXBRIContext
    at com.sun.xml.ws.fault.SOAPFaultBuilder.<clinit>(SOAPFaultBuilder.java:561)
    at java.lang.J9VMInternals.initializeImpl(Native Method)
    at java.lang.J9VMInternals.initialize(J9VMInternals.java:200)
    ... 34 more

P.S Ce service Web fonctionne sur Tomcat, mais a échoué sous WebSphere uniquement

Solution

Com.ibm.xml.xlxp2.jaxb.JAXBContextImpl est situé dans WAS APPSERVER PROFILE \ plugins \ com.ibm.ws.prereq.xlxp.jar et la bibliothèque Metro, webservices-rt.jar , en contiennent également un de l’instance com.sun.xml.bind.v2.runtime.JAXBContextImpl . Lorsque l’exception est déclenchée, WAS utilise deux instances différentes pour effectuer la même tâche de liaison JAXB et déclencher une exception incompatible «java.lang.ClassCastException».

Pour résoudre ce problème, assurez-vous que WAS utilise toujours la même instance.

  1. Dans l’écran de configuration WAS, définissez le chargeur de classe du module sur

Parent-premier “.

  1. Dans le dossier WAS, créez un dossier “ classes ” sous le dossier racine WAS et

insérez webservices-rt.jar , par exemple,` WAS APPSERVER PROFILE \ classes \ webservices-rt.jar`.

Redémarrez l’instance WAS, WAS chargera toujours votre webservices-rt.jar . Un sale chemin, mais ça marche :).

lien://tag/jax-ws/[jax-ws]lien://tag/metro/[metro]lien://tag/web-services/[services web]lien://tag/websphere/[websphere]