HOWTO: CXF JAX-WS Web Services on WebSphere AS 7

Open SourceI spent many hours to get this result, sinc related informations are scattered on the web, so I think it’s good to share it!

For JEE application development, I frequently use Eclipse and Maven; I don’t use (and don’t want to use) IBM/Rational products, such as Rational Software Delivery Platform (the so-called RAD).

If you develop JAX-WS Web Services, you can meet some problems to deploy on the WebSphere Application Server (the so-called WAS); yes, because in spite of the portability of Java, the fit of the IBM puzzle pieces remains obscure as long as you do not want to the reproducibility of the binary to be an important factor for the quality of your development process and product.

The reproducibility, must be independent of time, the licenses for commercial products, tools and people who worked on the project. The source code should allow you to build all the final results or installable executable.

This is one of the reasons why, in development projects, I use Maven and because in this, for web services, I used Apache CXF.

But the non-functional requirement really interesting for this article was the target environment: WebSphere Application Server 7.

The first reference below, is reported by the official CXF project wiki and it’s available here:

http://cxf.apache.org/docs/application-server-specific-configuration-guide.html#ApplicationServerSpecificConfigurationGuide-ForWebSphere6.1.0.29%2CV7andV8

Here they refer to a set of libraries, but I have to slightly correct, since in my case the set indicated did not work:

aopalliance-1.0.jar
commons-logging-1.1.1.jar
cxf-api-2.7.3.jar
cxf-rt-bindings-soap-2.7.3.jar
cxf-rt-core-2.7.3.jar
cxf-rt-databinding-jaxb-2.7.3.jar
cxf-rt-frontend-jaxws-2.7.3.jar
cxf-rt-frontend-simple-2.7.3.jar
cxf-rt-transports-http-2.7.3.jar
FastInfoset-1.2.2.jar
geronimo-activation_1.1_spec-1.0.2.jar
geronimo-annotation_1.0_spec-1.1.1.jar
geronimo-javamail_1.4_spec-1.3.jar
geronimo-jaxws_2.1_spec-1.0.jar
geronimo-stax-api_1.0_spec-1.0.1.jar
geronimo-ws-metadata_2.0_spec-1.1.2.jar
jaxb-api-2.1.jar
jaxb-impl-2.1.7.jar
neethi-3.0.2.jar
org.apache.servicemix.bundles.saaj-impl-1.3.18_1.jar
spring-aop-3.1.3.RELEASE.jar
spring-asm-3.1.3.RELEASE.jar
spring-beans-3.1.3.RELEASE.jar
spring-context-3.1.3.RELEASE.jar
spring-core-3.1.3.RELEASE.jar
spring-expression-3.1.3.RELEASE.jar
spring-web-3.1.3.RELEASE.jar
stax2-api-3.1.1.jar
woodstox-core-asl-4.1.4.jar
wsdl4j-1.6.2.jar
xmlschema-core-2.0.3.jar

Second issue: how to get Maven dependencies work with the right set of libraries?

In my POM I used these dependencies:

    <properties>
        <cxf.version>2.7.3</cxf.version>
        <spring.version>3.1.3.RELEASE</spring.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>${cxf.version}</version>
            <exclusions>
                <exclusion>
                    <artifactId>asm</artifactId>
                    <groupId>asm</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>cxf-rt-bindings-xml</artifactId>
                    <groupId>org.apache.cxf</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>cxf-rt-ws-addr</artifactId>
                    <groupId>org.apache.cxf</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>cxf-rt-ws-policy</artifactId>
                    <groupId>org.apache.cxf</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>xml-resolver</artifactId>
                    <groupId>xml-resolver</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.neethi</groupId>
            <artifactId>neethi</artifactId>
            <version>3.0.2</version>
            <exclusions>
                <exclusion>
                    <artifactId>stax-api</artifactId>
                    <groupId>javax.xml.stream</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.fastinfoset</groupId>
            <artifactId>FastInfoset</artifactId>
            <version>1.2.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.geronimo.specs</groupId>
            <artifactId>geronimo-jaxws_2.1_spec</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.geronimo.specs</groupId>
            <artifactId>geronimo-stax-api_1.0_spec</artifactId>
            <version>1.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.geronimo.specs</groupId>
            <artifactId>geronimo-annotation_1.0_spec</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.geronimo.specs</groupId>
            <artifactId>geronimo-ws-metadata_2.0_spec</artifactId>
            <version>1.1.2</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.messaging.saaj</groupId>
            <artifactId>saaj-impl</artifactId>
            <version>1.3.18</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.ws.security</groupId>
            <artifactId>wss4j</artifactId>
            <version>1.6.10</version>
        </dependency>
    </dependencies>

Have care to fix the MANIFEST too, adding the appropriate configuration parameter specific to WebSphere, documented here http://pic.dhe.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=%2Fcom.ibm.websphere.express.doc%2Finfo%2Fexp%2Fae%2Ftwbs_thirdparty.html; you can get this using the Maven WAR plugin:

            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                        </manifest>
                        <manifestEntries>
                            <DisableIBMJAXWSEngine>TRUE</DisableIBMJAXWSEngine>
                        </manifestEntries>
                    </archive>
                </configuration>
            </plugin>

Last trick, again in the article mentioned above, you can notice the nod to the famous class loader of WebSpehere, which must be obviously configured; here is an extract of the salient point:

Procedure

  1. Set the class loader policy to Classes loaded with local class loader first (parent last) at the module level.

Changing the class loader policy to parent last ensures that the external third-party JAX-WS run time and their dependent library JAR files are first in the class loader search path, thereby ensuring that the third-party implementation is used instead of the WebSphere Application Server.

  1. In the administrative console, click Applications > Application Types > WebSphere enterprise applications >application_name > Class loading and update detection.
  2. Under Class reloading options, select Override class reloading settings for Web and EJB modules .
  3. Under Class loader order, select Class loader order property to Classes loaded with local class loader first (parent last).
  1. Click OK, and then Save to save your changes.

That’s all.

Happy coding!!

Tagged , , , , . Bookmark the permalink.