Log4J 影响 JAXB

Log4J Impacting JAXB

我正在将 SOAP WS 应用程序从 WL10 迁移到 WL12。我们遇到了 JAXB 如何解释此 XML 元素的问题:

<sch:testVar xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>

在 WL10 中,JAXB 正确地将其编组为空对象。在 WL12 中,JAXB 将其转换为空字符串。

经过对 class 路径和数据绑定提供程序的大量研究,我们终于找到了问题... Log4J。

我们正在使用 Maven 并添加依赖项 Log4J 1.2.16 改变了一切。当 Log4J 在应用程序中时,上面的 XML 呈现为空字符串。仅从 pom 中删除 Log4J 依赖项,JAXB 将上面的 XML 呈现为 null。

有谁知道为什么 Log4J 会影响 JAXB?

几个注意事项:

maven 构建的依赖树如下:

[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ RJM-Training-SOAP-WS ---
[INFO] com.mycompany:RJM-Training-SOAP-WS:war:0.0.1-SNAPSHOT
[INFO] +- org.springframework:spring-core:jar:3.1.1.RELEASE:compile
[INFO] |  +- org.springframework:spring-asm:jar:3.1.1.RELEASE:compile
[INFO] |  \- commons-logging:commons-logging:jar:1.1.1:compile
[INFO] +- org.springframework:spring-context-support:jar:3.1.1.RELEASE:compile
[INFO] |  +- org.springframework:spring-beans:jar:3.1.1.RELEASE:compile
[INFO] |  \- org.springframework:spring-context:jar:3.1.1.RELEASE:compile
[INFO] |     \- org.springframework:spring-expression:jar:3.1.1.RELEASE:compile
[INFO] +- org.springframework:spring-web:jar:3.1.1.RELEASE:compile
[INFO] |  \- aopalliance:aopalliance:jar:1.0:compile
[INFO] +- org.springframework:spring-tx:jar:3.1.1.RELEASE:compile
[INFO] |  \- org.springframework:spring-aop:jar:3.1.1.RELEASE:compile
[INFO] +- org.springframework.ws:spring-ws-core:jar:2.1.2.RELEASE:compile
[INFO] |  +- org.springframework.ws:spring-xml:jar:2.1.2.RELEASE:compile
[INFO] |  +- org.springframework:spring-oxm:jar:3.1.3.RELEASE:compile
[INFO] |  |  \- commons-lang:commons-lang:jar:2.5:compile
[INFO] |  +- org.springframework:spring-webmvc:jar:3.1.3.RELEASE:compile
[INFO] |  \- wsdl4j:wsdl4j:jar:1.6.1:compile
[INFO] \- log4j:log4j:jar:1.2.16:compile

我们使用的 JAXB 上下文如下:

[user@server logs]$ grep JAXBContext WSServer01.log.out 
[Loaded javax.xml.bind.JAXBContext from /opt/weblogic/wl12.1.2.0/wlserver/../oracle_common/modules/endorsed/javax-xml-bind.jar]
[Loaded com.sun.xml.bind.v2.runtime.JAXBContextImpl from file:/opt/weblogic/wl12.1.2.0/oracle_common/modules/com.sun.xml.bind.jaxb-impl_2.2.jar]
[Loaded com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder from file:/opt/weblogic/wl12.1.2.0/oracle_common/modules/com.sun.xml.bind.jaxb-impl_2.2.jar]
[Loaded com.sun.xml.bind.v2.runtime.JAXBContextImpl from file:/opt/weblogic/wl12.1.2.0/oracle_common/modules/com.sun.xml.bind.jaxb-impl_2.2.jar]
[Loaded com.sun.xml.bind.v2.runtime.JAXBContextImpl from file:/opt/weblogic/wl12.1.2.0/oracle_common/modules/com.sun.xml.bind.jaxb-impl_2.2.jar]
[Loaded com.sun.xml.bind.v2.runtime.JAXBContextImpl from file:/opt/weblogic/wl12.1.2.0/oracle_common/modules/com.sun.xml.bind.jaxb-impl_2.2.jar]
[Loaded com.sun.xml.bind.v2.runtime.JAXBContextImpl from file:/opt/weblogic/wl12.1.2.0/oracle_common/modules/com.sun.xml.bind.jaxb-impl_2.2.jar]
[Loaded com.sun.xml.bind.v2.runtime.JAXBContextImpl from file:/opt/weblogic/wl12.1.2.0/oracle_common/modules/com.sun.xml.bind.jaxb-impl_2.2.jar]
[Loaded com.sun.xml.bind.v2.runtime.JAXBContextImpl from file:/opt/weblogic/wl12.1.2.0/oracle_common/modules/com.sun.xml.bind.jaxb-impl_2.2.jar]

我进入代码并记录了使用的 JAXB class。在这两种情况下都是一样的。

file:/opt/weblogic/wl12.1.2.0/oracle_common/modules/endorsed/javax-xml-bind.jar!/javax/xml/bind/JAXBContext.class

有人在内部找出了问题的根本原因。解决方案是更改 Spring WS 使用的 messageFactory 实现。我将这个 bean 定义添加到我的项目中:

<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">
     <property name="messageFactory">
        <bean class="com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl"/>
     </property>
</bean>

加载 Log4J 1.x 时,它正在加载较新版本的 SAAJ API,这导致了我们的 nillable 问题。 Log4J 2.x 之所以有效,是因为它默认使用较旧的 SAAJ 实现。

如果我们指定上面列出的 messageFactory,我们就可以使用 Log4J 1.x。