JDK6 和 xml-api 之间的冲突

Conflicts between JDK6 and xml-apis

OpenSAML从1.1升级到2.6.1后,需要xerces-impl依赖,启动时出现如下堆栈:

 Caused by: java.lang.ClassCastException: org.apache.xerces.jaxp.datatype.DatatypeFactoryImpl cannot be cast to javax.xml.datatype.DatatypeFactory
       at javax.xml.datatype.DatatypeFactory.newInstance(DatatypeFactory.java:131) ~[xml-apis-1.4.01.jar:1.6.0_45]
       at com.sun.xml.bind.DatatypeConverterImpl.<clinit>(DatatypeConverterImpl.java:831) ~[glassfish.jaxb_1.0.0.0_2-1-12.jar:2.1.12]
       ... 68 common frames omitted

xerces-impl 重新定义了一些 jre 类 并附带了 xml-apis 重新定义了一些 jre 接口。 org.apache.xerces.jaxp.datatype.DatatypeFactoryImpl 来自 xerces-impl.

我在 weblogic 10.3.5 和 JDK 6.

我读 Dealing with "Xerces hell" in Java/Maven? and try to exclude xml-apis but xerces-impl throws NoClassDefFoundError. Copying xml-apis and xerces-impl in jre/lib/endorsed throws ClassCastException too (http://docs.oracle.com/javase/6/docs/technotes/guides/standards/).

在启动命令中添加 -Djavax.xml.datatype.DatatypeFactory=com.sun.org.apache.xerces.internal.jaxp.datatype.DatatypeFactoryImpl 抛出:

 Caused by: java.lang.ClassCastException: org.apache.xerces.jaxp.SAXParserFactoryImpl cannot be cast to javax.xml.parsers.SAXParserFactory
    at javax.xml.parsers.SAXParserFactory.newInstance(SAXParserFactory.java:128) ~[xml-apis-1.4.01.jar:1.6.0_45]
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.getXMLReader(AbstractUnmarshallerImpl.java:80) ~[na:1.6.0_45]

然后添加 -Djavax.xml.parsers.SAXParserFactory=com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl 抛出:

 Caused by: java.lang.ClassCastException: com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl cannot be cast to javax.xml.parsers.SAXParserFactory
    at javax.xml.parsers.SAXParserFactory.newInstance(Unknown Source)
    at ch.qos.logback.core.joran.event.SaxEventRecorder.buildSaxParser(SaxEventRecorder.java:79)

我不知道接下来要做什么。有什么想法吗?

WebLogic 在类路径中包含许多此类库的自己的版本,它们可能会干扰您的应用程序。尝试将这样的部分添加到 weblogic.xml 文件:

<weblogic-web-app>

  <container-descriptor>
    <prefer-application-packages>
        <package-name>org.slf4j.*</package-name>
        <package-name>org.slf4j.helpers.*</package-name>
        <package-name>org.slf4j.impl.*</package-name>
        <package-name>org.slf4j.spi.*</package-name>
    </prefer-application-packages>
  </container-descriptor>
  ...
</weblogic-web-app>

该示例显示了 slf4j 的包;我不确定它们将用于 xerces。如果您有权访问 wls-cat tool,那应该有助于解决问题。


更新

WLS 和您的应用程序之间的类路径冲突可以通过以下三种方式之一解决。

  1. 将程序包添加到 <prefer-application-packages> 元素,以便应用优先
  2. 更改 POM 以注意特定依赖项是 provided by WLS
  3. 从 POM 中完全排除依赖项。

我建议使用 mvn dependency:tree 与旧版本的 OpenSAML,注意依赖关系。然后更改为新的 OpenSAML 版本,并注意引入了哪些新的依赖项。查看 WLS 服务器的 modules 目录以查看 WLS 使用的库,将其与新 OpenSAML 的更改依赖项进行交叉引用版本,并决定 3 种可能性中的哪一种似乎是最合适的。例如,如果您看到 WLS 使用比您的应用程序更早版本的库,您可能想要使用选项 1。执行此操作直到您可以部署应用程序,然后使用 wls-cat 完成工作。

除了javax.xml.bind作为首选应用

<wls:package-name>javax.xml.bind.*</wls:package-name>

在 weblogic.xml 中,添加 jaxb 依赖项解决了我的问题:

<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
    <version>${jaxb-impl.version}</version>
</dependency>
<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>${jaxb-api.version}</version>
</dependency>