Problem loading XML namespace from CXF module and custom Spring module
sergiopolog Apr 19, 2017 8:38 AMHi,
I'm trying to deploy a webapp to JBoss EAP 6.4 that uses Apache CXF to create a client to consume a WebService, and Spring 3.2.18
Webapp is packaged in a war file, and then in a ear file, following the next structure, to use cxf module within jboss: (jboss-deployment-structure.xml):
<?xml version="1.0" encoding="UTF-8"?> <jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2"> <ear-subdeployments-isolated>false</ear-subdeployments-isolated> <deployment> <exclude-subsystems> <subsystem name="jaxrs"/> <subsystem name="webservices"/> </exclude-subsystems> </deployment> <sub-deployment name="myapp.war"> <local-last value="true"/> <dependencies> <module name="org.apache.cxf"/> <module name="org.apache.cxf.impl" meta-inf="import"/> <module name="org.springframework.spring" slot="3.2.18.RELEASE" meta-inf="import" /> <module name="org.quartz-scheduler.quartz" slot="1.8.3"/> <module name="org.apache.ibatis.ibatis-sqlmap" slot="2.3.4.726"/> <module name="org.aspectj" slot="1.6.1"/> <module name="org.slf4j"/> </dependencies> </sub-deployment> </jboss-deployment-structure>
I have created a static modules for Spring and its dependencies, for "org.apache.cxf" module works with spring:
<?xml version="1.0" encoding="UTF-8"?> <module xmlns="urn:jboss:module:1.1" name="org.springframework.spring" slot="3.2.18.RELEASE"> <resources> <resource-root path="aopalliance-1.0.jar"/> <resource-root path="spring-aop-3.2.18.RELEASE.jar"/> <resource-root path="spring-beans-3.2.18.RELEASE.jar"/> <resource-root path="spring-context-3.2.18.RELEASE.jar"/> <resource-root path="spring-context-support-3.2.18.RELEASE.jar"/> <resource-root path="spring-core-3.2.18.RELEASE.jar"/> <resource-root path="spring-expression-3.2.18.RELEASE.jar"/> <resource-root path="spring-jdbc-3.2.18.RELEASE.jar"/> <resource-root path="spring-jms-3.2.18.RELEASE.jar"/> <resource-root path="spring-orm-3.2.18.RELEASE.jar"/> <resource-root path="spring-test-3.2.18.RELEASE.jar"/> <resource-root path="spring-tx-3.2.18.RELEASE.jar"/> <resource-root path="spring-web-3.2.18.RELEASE.jar"/> </resources> <dependencies> <module name="org.quartz-scheduler.quartz" slot="1.8.3" optional="true"/> <module name="org.apache.ibatis.ibatis-sqlmap" slot="2.3.4.726" optional="true"/> <module name="org.aspectj" slot="1.6.1" optional="true"/> <module name="org.apache.commons.logging"/> <module name="javaee.api"/> <module name="org.jboss.vfs"/> </dependencies> </module>
Quartz:
<?xml version="1.0" encoding="UTF-8"?> <module xmlns="urn:jboss:module:1.1" name="org.quartz-scheduler.quartz" slot="1.8.3"> <resources> <resource-root path="quartz-1.8.3.jar"/> <resource-root path="quartz-oracle-1.8.3.jar"/> </resources> <dependencies> <module name="org.slf4j"/> </dependencies> </module>
Ibatis:
<?xml version="1.0" encoding="UTF-8"?> <module xmlns="urn:jboss:module:1.1" name="org.apache.ibatis.ibatis-sqlmap" slot="2.3.4.726"> <resources> <resource-root path="ibatis-sqlmap-2.3.4.726.jar"/> </resources> <dependencies> <module name="org.apache.commons.logging"/> <module name="javax.api"/> </dependencies> </module>
Aspectj:
<?xml version="1.0" encoding="UTF-8"?> <module xmlns="urn:jboss:module:1.1" name="org.aspectj" slot="1.6.1"> <resources> <resource-root path="aspectjrt-1.6.1.jar"/> <resource-root path="aspectjweaver-1.6.1.jar"/> </resources> </module>
Initially application starts correctly, but when I add this CXF configuration in a Spring xml file:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/beans" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns:beans="http://www.springframework.org/schema/beans"
  xmlns:jee="http://www.springframework.org/schema/jee"
  xmlns:util="http://www.springframework.org/schema/util"
  xmlns:cxf="http://cxf.apache.org/core"
  xmlns:jaxws="http://cxf.apache.org/jaxws"
  xmlns:soap="http://cxf.apache.org/bindings/soap"
  xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
       http://www.springframework.org/schema/jee
       http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
       http://www.springframework.org/schema/util 
       http://www.springframework.org/schema/util/spring-util-3.2.xsd
       http://cxf.apache.org/core
       http://cxf.apache.org/schemas/core.xsd
       http://cxf.apache.org/jaxws
       http://cxf.apache.org/schemas/jaxws.xsd
       http://cxf.apache.org/bindings/soap
       http://cxf.apache.org/schemas/configuration/soap.xsd">
  <!-- BUS de CXF -->
  <cxf:bus name="wsBusCxf">
       <cxf:features>
            <!- Para ver las trazas de las peticiones enviadas ->
            <cxf:logging/>
       </cxf:features>
  </cxf:bus>
  <jee:jndi-lookup id="loginSForceUrl" jndi-name="${config.jndi.login.sforce.url}"/>
  <beans:bean id="loginSForceUrlStr" factory-bean="loginSForceUrl" factory-method="toString"/>
  <!-- Client WS -->
  <jaxws:client
            id="loginSForceWS"
            bus="wsBusCxf"
            serviceClass="com.sforce.soap.enterprise.Soap"
            wsdlLocation="META-INF/wsdl/EnterprisePruebasWSService.wsdl"
            serviceName="SforceService"
            endpointName="Soap"
            address="#loginSForceUrlStr">
       <jaxws:binding>
            <soap:soapBinding version="1.2"/>
       </jaxws:binding>
  </jaxws:client>
</beans:beans>
It causes this error:
Caused by: org.springframework.beans.FatalBeanException: Class [org.apache.cxf.jaxws.spring.NamespaceHandler] for namespace [http://cxf.apache.org/jaxws] does not implement the [org.springframework.beans.factory.xml.NamespaceHandler] interface
at org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver.resolve(DefaultNamespaceHandlerResolver.java:126) [spring-beans-3.2.18.RELEASE.jar:3.2.18.RELEASE]
at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1427) [spring-beans-3.2.18.RELEASE.jar:3.2.18.RELEASE]
at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1422) [spring-beans-3.2.18.RELEASE.jar:3.2.18.RELEASE]
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:187) [spring-beans-3.2.18.RELEASE.jar:3.2.18.RELEASE]
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:147) [spring-beans-3.2.18.RELEASE.jar:3.2.18.RELEASE]
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:101) [spring-beans-3.2.18.RELEASE.jar:3.2.18.RELEASE]
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:495) [spring-beans-3.2.18.RELEASE.jar:3.2.18.RELEASE]
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:391) [spring-beans-3.2.18.RELEASE.jar:3.2.18.RELEASE]
... 47 more
It seems to be a Classloader issue, because org.apache.cxf.jaxws.spring.NamespaceHandler has this classloader (got from .getClassLoader()):
ModuleClassLoader for Module "org.apache.cxf.impl:main" from local module loader @306a4bda (finder: local module finder @1299ee0b (roots: C:\Programas\jboss-eap-6.4\modules,C:\Programas\jboss-eap-6.4\modules\system\layers\base))
and org.springframework.beans.factory.xml.NamespaceHandler has another classloader:
ModuleClassLoader for Module "org.springframework.spring:3.2.18.RELEASE" from local module loader @306a4bda (finder: local module finder @1299ee0b (roots: C:\Programas\jboss-eap-6.4\modules,C:\Programas\jboss-eap-6.4\modules\system\layers\base))
Can you help me?