Русский English Tags View Sergey Zolotaryov's profile on LinkedIn Sign-in
How to run your CXF application in WebSphere
Permanent link 06-06-2019 anydoby java

The job of an IT consultant is at times dangerous and sweaty. Apart from the bleeding edge tech you have to deal with the bloody legacy enterprise. Some time ago I had to adapt a web application to run within an IBM WebSphere 8.x.

The application is a simple bunch of web services which runs normally in a servlet container. Regular Spring + CXF with SOAP services, but when packed into an ear archive and installed into a full fledged application container it boomed:


Caused by: org.apache.cxf.bus.extension.ExtensionException: Could not load extension class org.apache.cxf.ws.policy.AssertionBuilderRegistryImpl.
at org.apache.cxf.bus.extension.Extension.tryClass(Extension.java:183)
at org.apache.cxf.bus.extension.Extension.getClassObject(Extension.java:199)
at org.apache.cxf.bus.extension.ExtensionManagerImpl.activateAllByType(ExtensionManagerImpl.java:144)
at org.apache.cxf.bus.extension.ExtensionManagerBus.<init>(ExtensionManagerBus.java:179)
at org.apache.cxf.bus.extension.ExtensionManagerBus.<init>(ExtensionManagerBus.java:191)
at org.apache.cxf.bus.spring.SpringBus.<init>(SpringBus.java:45)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:86)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:58)
at java.lang.reflect.Constructor.newInstance(Constructor.java:542)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:148)
... 108 more
Caused by: java.lang.IncompatibleClassChangeError: org.apache.neethi.AssertionBuilderFactory
at java.lang.ClassLoader.defineClassImpl(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:324)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:155)
at com.ibm.ws.classloader.CompoundClassLoader._defineClass(CompoundClassLoader.java:857)
at com.ibm.ws.classloader.CompoundClassLoader.localFindClass(CompoundClassLoader.java:765)
at com.ibm.ws.classloader.CompoundClassLoader.loadClass(CompoundClassLoader.java:588)
at java.lang.ClassLoader.loadClass(ClassLoader.java:731)
at java.lang.ClassLoader.defineClassImpl(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:324)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:155)
at com.ibm.ws.classloader.CompoundClassLoader._defineClass(CompoundClassLoader.java:857)
at com.ibm.ws.classloader.CompoundClassLoader.localFindClass(CompoundClassLoader.java:765)
at com.ibm.ws.classloader.CompoundClassLoader.loadClass(CompoundClassLoader.java:588)
at java.lang.ClassLoader.loadClass(ClassLoader.java:731)
at org.apache.cxf.bus.extension.Extension.tryClass(Extension.java:164)

The solution here is quite simple: after searching through forums I found that WebSphere is also using Apache Neethi. Obviously of an older version. You got it right? I would expect that it keeps its stuff to itself, but it exposes these packages to it running applications. In short there are two options: either not use CXF and stick to the JEE API's provided by the container, or go here:


Enterprise Applications > your_ear_app > Class loader

Class loader order -> Classes loaded with local class loader first (parent last)
WAR class loader policy -> Single class loader for application

and then here:


Enterprise Applications > your_ear_app > Manage Modules > your_war_module

Class loader order -> Classes loaded with local class loader first (parent last)

Unfortunately these settings cannot be setup in a normal way via a descriptor or a manifest file in the application archive. Only manually with a mouse.

After this step forward I got another error:


java.lang.VerifyError: JVMVRFY013 class loading constraint violated; class=org/apache/cxf/jaxws/binding/soap/SOAPBindingImpl, method=getMessageFactory()Ljavax/xml/soap/Mes
sageFactory;, pc=0
at java.lang.J9VMInternals.verifyImpl(Native Method)
at java.lang.J9VMInternals.verify(J9VMInternals.java:94)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:169)
at org.apache.cxf.jaxws.support.JaxWsEndpointImpl.createJaxwsBinding(JaxWsEndpointImpl.java:532)
at org.apache.cxf.jaxws.support.JaxWsEndpointImpl.<init>(JaxWsEndpointImpl.java:157)
at org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.createEndpoint(JaxWsServiceFactoryBean.java:249)
at org.apache.cxf.frontend.AbstractWSDLBasedEndpointFactory.createEndpoint(AbstractWSDLBasedEndpointFactory.java:173)
at org.apache.cxf.frontend.ServerFactoryBean.create(ServerFactoryBean.java:159)
at org.apache.cxf.jaxws.JaxWsServerFactoryBean.create(JaxWsServerFactoryBean.java:211)
at org.apache.cxf.jaxws.EndpointImpl.getServer(EndpointImpl.java:456)
at org.apache.cxf.jaxws.EndpointImpl.doPublish(EndpointImpl.java:334)
at org.apache.cxf.jaxws.EndpointImpl.publish(EndpointImpl.java:251)
at org.apache.cxf.jaxws.spi.ProviderImpl.createAndPublishEndpoint(ProviderImpl.java:155)
at javax.xml.ws.Endpoint.publish(Endpoint.java:255)

The solution here was not so straightforward. The general approach however is to: go to the source jar where the org.apache.cxf.jaxws.binding.soap.SOAPBindingImpl lies, look into which dependency is containing the javax.xml.soap.MessageFactory class; it is a SOAP API, which is included in the JDK 8, but you can also carry it around with you, if not sure you will be running in the Java 8 environment. In my case it was pulled in by the org.apache.servicemix.specs.saaj-api. The class is already loaded by the JVM bootloader and we are trying to load it from an external jar, application server VM thinks this is wrong. So we need to exclude the API from our war file:


    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <configuration>
                    <packagingExcludes>WEB-INF/lib/org.apache.servicemix.specs.saaj-api*</packagingExcludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

Fortunately after removing this dependency I had no other issues and the application is running fine.

Good luck searching your classpath.

Add a comment

Previous article Configuring Bower authentication in Jenkins