Metro on WebSphere 7 – com.ibm.xml.xlxp2.jaxb.JAXBContextImpl incompatible exception

Problem

Developed a SOAP web service via Metro 2.0.1 (webservices-rt.jar), integrate with Spring via jaxws-spring-1.8.jar and deployed on WebSphere Application Server (WAS) version 7.0.0.13 . See web service below :

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();

    }
}

If everything is fine, the service is work as expected, but, when “userBo.listUser()” hit error and throwing a SOAPException back to the web service’s client :

Client get this :


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

WAS log file showing this :


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 This web service is working on Tomcat, but failed on WebSphere only

Solution

The com.ibm.xml.xlxp2.jaxb.JAXBContextImpl is located at WAS_APPSERVER_PROFILE\plugins\com.ibm.ws.prereq.xlxp.jar, and Metro library, webservices-rt.jar, also contain one of the instance com.sun.xml.bind.v2.runtime.JAXBContextImpl . When exception raised, WAS is using two different instance to perform a same JAXB binding task, and raise an “java.lang.ClassCastException” incompatible exception.

To fix it, just make sure WAS is using same instance always.

  1. In WAS configuration screen, set module class loader to “parent-first“.
  2. In WAS folder, create a “classes” folder under WAS root folder and put webservices-rt.jar inside, for example, WAS_APPSERVER_PROFILE\classes\webservices-rt.jar.

Restart WAS instance, now WAS will load your webservices-rt.jar always. A dirty way, but it work :).

4 comments on “Metro on WebSphere 7 – com.ibm.xml.xlxp2.jaxb.JAXBContextImpl incompatible exception

  1. i have found a nother way to get the same result without changing anything in the
    WAS.
    aparently if ou place a
    jaxb.properties in the /src/main/resources path with the folowing string.
    javax.xml.bind.context.factory=com.sun.xml.bind.v2.ContextFactory

    websphere loads and uses only this contextFactory and the exception is never thrown 🙂

    Reply
    1. Can you specify where exactly did you put jaxb.properties file?
      Does it have to be in the same package as the service implementation?
      I tried adding it but it doesn’t work for me.

      Thanks in advance,
      Marko

      Reply
      1. jaxb.properties
        with single line: javax.xml.bind.context.factory=com.sun.xml.bind.v2.ContextFactory
        must be in package: com.sun.xml.ws.fault
        somewhere with your classes
        For other solutions you can check sources of: javax.xml.bind.ContextFinder.find
        http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/javax/xml/bind/ContextFinder.java#ContextFinder.find%28java.lang.String%2Cjava.lang.String%2Cjava.lang.ClassLoader%2Cjava.util.Map%29

        Reply

Leave a Comment

Your email address will not be published. Required fields are marked *