使用JAXB的ClassCastException - Websphere jar vs applicationl jar

时间:2016-05-05 14:58:59

标签: java tomcat jaxb websphere ibm-was

在尝试将Java对象转换为字符串时,我遇到了类强制转换异常。我在我的lib文件夹中包含了JAXB-2.1 jar。在部署到WAS时,我已经将类加载器策略更改为最后一个父级,以便首先拾取本地库中的jar。但是这仍然会抛出带有以下消息的classcast异常。这个错误的原因是什么?

javax.xml.bind.JAXBException: ClassCastException: attempting to cast jar:file:/opt/was7/base/crm/java/jre/lib/rt.jar!/javax/xml/bind/JAXBContext.class to wsjar:file:/prod/wesadm/wes/was7/base/profiles/sadasd/installedApps/asdadad/myapp.ear/myapp_war.war/WEB-INF/lib/jaxb-api-2.1.jar!/javax/xml/bind/JAXBContext.class.  Please make sure that you are specifying the proper ClassLoader.
        at javax.xml.bind.ContextFinder.handleClassCastException(ContextFinder.java:96)
        at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:214)
        at javax.xml.bind.ContextFinder.find(ContextFinder.java:372)
        at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:574)
        at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:522)
        at com.my.MyClass.convertObjectToXML()

这是 convertObjectToXML()方法。

private <T> String convertObjectToXMLString(T obj) throws JAXBException {
        JAXBContext jaxbContext = JAXBContext.newInstance(obj.getClass());
        Marshaller marshaller = jaxbContext.createMarshaller();

        StringWriter sw = new StringWriter();
        marshaller.marshal(obj, sw);

        return sw.toString();

    }

当部署到Tomcat时,此逻辑工作正常。我无法弄清楚为什么WAS罐子被拿起来,尽管我提到了类加载器作为父级的最后一个。

3 个答案:

答案 0 :(得分:1)

您似乎将JAXB api jar与您的应用捆绑在一起。从您的应用中删除它们,它会工作。这些jar已经与WebSphere捆绑在一起(实际上它们是JRE的一部分)并且它会导致类加载器异常,因为存在两个相同类的版本

答案 1 :(得分:0)

javax.xml.bind.ContextFinder.find(Class[] classes, Map properties)  将首先查找jaxb.property。 如果未找到,则尝试按以下顺序搜索/创建工厂:

  1. 系统属性 javax.xml.bind.context.factory
  2. 使用OSGi ServiceLoader查找
  3. 搜索META-INF服务
  4. 我相信您的程序不会在程序包com.my中提供jaxb.property。 因此工厂类从Websphere JDK /库加载,它将返回JAXBContext类的对象。 但是该类与WAR中的类不同,因此javax.xml.bind.ContextFinder抛出ClassCastException

答案 2 :(得分:0)

在将应用程序迁移到Websphere 9时,我遇到了异常。

java.lang.Exception: javax.xml.bind.JAXBException: ClassCastException: attempting to cast jar:file:/D:/WebSphere/AppServer/endorsed_apis/jaxb-api.jar!/javax/xml/bind/JAXBContext.class to wsjar:file:/D:/sites/XXXX.ear/Web.war/WEB-INF/lib/jaxb-api-2.2.10.jar!/javax/xml/bind/JAXBContext.class.  Please make sure that you are specifying the proper ClassLoader.    

我从应用程序中排除了jar的所有引用,这些引用现在是IBM jdk的一部分。例如STAX-API

    <dependency>
        <groupId>org.apache.xmlbeans</groupId>
        <artifactId>xmlbeans</artifactId>
        <version>2.6.0</version> 
        <exclusions>
            <exclusion>
                <groupId>stax</groupId>
                <artifactId>stax-api</artifactId>
            </exclusion>
            <exclusion>
                <groupId>xml-apis</groupId>
                <artifactId>xml-apis</artifactId>
            </exclusion>
        </exclusions>
    </dependency>