Main Tutorials

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 :).

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
4 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
areizero Developer
7 years ago

You can find a complete Guide for Metro, CXF and Axis on IBM Websphere (WAS) in the next link (Offical guides), some libs can generate conflicts with the WAS .jar libs.

http://public.dhe.ibm.com/software/dw/wes/1001_thaker/1001_thaker.pdf
http://www.ibm.com/developerworks/websphere/library/techarticles/1001_thaker/1001_thaker.html

tiago
11 years ago

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 🙂

Marko
11 years ago
Reply to  tiago

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

rafd
10 years ago
Reply to  Marko

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