Reputation: 61
I am porting an application from JBoss 4 to JBoss 6.1 EAP. This application uses cxf with spring. Our client's requirement is that we will not change (or add) modules for jboss.
In the jboss cxf module, there is an optional dependency to spring, but by default there is no spring module. I was wondering:
If I don't create a spring module and add the spring jars to the application lib directory, I get the following error:
09:19:44,203 WARN [org.jboss.modules] (MSC service thread 1-1) Failed to define class org.apache.cxf.transport.servlet.CXFServlet in Module "org.apache.cxf.impl:main" from local module loader @1f06dc3 (finder: local module finder @1b64e6a (roots: C:\dev\jboss-eap-6.1\modules,C:\dev\jboss-eap-6.1\modules\system\layers\base)): java.lang.LinkageError: Failed to link org/apache/cxf/transport/servlet/CXFServlet (Module "org.apache.cxf.impl:main" from local module loader @1f06dc3 (finder: local module finder @1b64e6a (roots: C:\dev\jboss-eap-6.1\modules,C:\dev\jboss-eap-6.1\modules\system\layers\base)))
at org.jboss.modules.ModuleClassLoader.defineClass(ModuleClassLoader.java:427) [jboss-modules.jar:1.2.0.Final-redhat-1]
at org.jboss.modules.ModuleClassLoader.loadClassLocal(ModuleClassLoader.java:260) [jboss-modules.jar:1.2.0.Final-redhat-1]
at org.jboss.modules.ModuleClassLoader$1.loadClassLocal(ModuleClassLoader.java:75) [jboss-modules.jar:1.2.0.Final-redhat-1]
at org.jboss.modules.Module.loadModuleClass(Module.java:526) [jboss-modules.jar:1.2.0.Final-redhat-1]
at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:188) [jboss-modules.jar:1.2.0.Final-redhat-1]
at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:444) [jboss-modules.jar:1.2.0.Final-redhat-1]
at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:432) [jboss-modules.jar:1.2.0.Final-redhat-1]
at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:399) [jboss-modules.jar:1.2.0.Final-redhat-1]
at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:399) [jboss-modules.jar:1.2.0.Final-redhat-1]
at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:374) [jboss-modules.jar:1.2.0.Final-redhat-1]
at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:119) [jboss-modules.jar:1.2.0.Final-redhat-1]
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:316) [rt.jar:1.6.0_17]
at java.lang.Class.forName0(Native Method) [rt.jar:1.6.0_17]
at java.lang.Class.forName(Class.java:247) [rt.jar:1.6.0_17]
at org.jboss.as.server.deployment.reflect.DeploymentClassIndex.classIndex(DeploymentClassIndex.java:54)
at org.jboss.as.ee.component.deployers.InterceptorAnnotationProcessor.processComponentConfig(InterceptorAnnotationProcessor.java:85) [jboss-as-ee-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
at org.jboss.as.ee.component.deployers.InterceptorAnnotationProcessor.deploy(InterceptorAnnotationProcessor.java:77) [jboss-as-ee-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:120)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [rt.jar:1.6.0_17]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [rt.jar:1.6.0_17]
at java.lang.Thread.run(Thread.java:619) [rt.jar:1.6.0_17]
Caused by: java.lang.NoClassDefFoundError: org/springframework/context/ApplicationListener
at java.lang.ClassLoader.defineClass1(Native Method) [rt.jar:1.6.0_17]
at java.lang.ClassLoader.defineClass(ClassLoader.java:616) [rt.jar:1.6.0_17]
at org.jboss.modules.ModuleClassLoader.doDefineOrLoadClass(ModuleClassLoader.java:344) [jboss-modules.jar:1.2.0.Final-redhat-1]
at org.jboss.modules.ModuleClassLoader.defineClass(ModuleClassLoader.java:422) [jboss-modules.jar:1.2.0.Final-redhat-1]
... 22 more
Upvotes: 3
Views: 2130
Reputation: 5673
SpringBeanAutowiringSupport
to integrate with your app's ApplicationContext. Further details below.I faced the same problem - migrating an app with Spring-managed JAX-WS endpoints to JBoss EAP 6 (AS 7).
The problem is that JBossWS in EAP 6 is a double-edged sword. It makes it very easy to setup JAX-WS endpoints, abstracting away all knowledge of the underlying CXF engine from your app, but it requires you to relinquish some control over those endpoints.
Instead of using CXF's Spring namespace and defining your endpoints as Spring beans sitting behind a single servlet, you should now remove those beans from the Spring context and define each one as a servlet in web.xml (even though they are not actually servlets!).
JBossWS will auto-detect those pseudo-servlets at runtime and will build the necessary CXF infrastructure behind them.
This is all well-and-good, but what if you need to inject some Spring-managed dependencies into your endpoints?
SpringBeanAutowiringSupport
to the rescue! Apparently this was the main reason for this class - to integrate Spring IoC with container-managed beans.
Have your endpoints extend this class, and then your dependencies can be injected via @Autowired
(or the like).
Note that you should still use ContextLoaderListener
as a listener-class in your web.xml to bootstrap your Spring ApplicationContext.
Note also that your app can now be totally agnostic of CXF - meaning you should not do any of the following:
classpath:META-INF/cxf/cxf.xml
)xmlns:jaxws="http://cxf.apache.org/jaxws"
)The downside is that your app can no longer use any advanced CXF-specific features, but hopefully this isn't necessary anyway.
Upvotes: 2