Deploying JAX-WS Services on Java 7 and Tomcat 7

Deploying JAX-WS Web Services on Java SE is easy. Annotating class with @WebService and using Endpoint.publish() with Java internal HTTP server is usually enough. What’s required for Tomcat deployment?

Reference implementations

JDK 6 and newer contains a JAX-WS reference implementation (JAX-WS RI), which is a stripped down version of Glassfish Metro. To be more precise, Metro = JAX-WS RI + WSIT + Servlet components.

JDK 7 and JDK 8 contain the latest specification JAX-WS API 2.2. This means that using Metro in JDK 7 / Tomcat 7 webapps is extremely easy: just put the webservices-rt.jar in the WEB-INF/lib and you are done.

(On older Tomcat and JDK versions, you had to fiddle with endorsed mechanism, see the appendix.)

Let’s create a very simple project in Tomcat 7 on Java 7.

A very simple project

A Tomcat-based JAX-WS project requires at least two files:

  • an actual @WebService implementation
  • JAX-WS Metro servlet configuration sun-jaxws.xml.

Let’s build a Maven-based project.

pom.xml

In pom.xml we’ll include just the Metro runtime implementation webservices-rt. This JAR has two dependencies: webservices-api and javax.annotation-api. However, we do not need these transitive dependencies, since they are already included either in the Java SE or in the Tomcat (see annotations-api.jar in Tomcat lib folder).

Therefore, let’s just include the webservices-api in the provided scope, thus excluding them from WEB-INF/lib folder of our WAR archive.

Besides that, we’ll configure the target Java version to JDK 7 and configure the WAR plugin not to expect web.xml, since we won’t be using it.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>sk.upjs.ics.novotnyr</groupId>
    <artifactId>metro-war-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <dependencies>
        <dependency>
            <groupId>org.glassfish.metro</groupId>
            <artifactId>webservices-rt</artifactId>
            <version>2.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.metro</groupId>
            <artifactId>webservices-api</artifactId>
            <version>2.3.1</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.3</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.6</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Sample class

A sample class can be quite straightforward

@WebService
public class DateService {
    public Date getCurrentDate() {
        return new Date();
    }
}

JAX-WS Deployment Descriptor

Remember that Tomcat is not a full-fledged Java EE container. Therefore, in order to publish our webservice, we need to attach some configuration.

Let’s create a sun-jaxws.xml and put it in the WEB-INF/lib. (This path is hardwired in Metro source code.)

<?xml version="1.0" encoding="UTF-8"?>
<endpoints xmlns='http://java.sun.com/xml/ns/jax-ws/ri/runtime'
        version='2.0'>
    <endpoint name='DateService'
            implementation='sk.upjs.ics.novotnyr.metrowardemo.DateService'
            url-pattern='/date'/>
</endpoints> 

We have created a simple service, specified the implementation class and, most importantly, configured an URL pattern for HTTP access.

Missing sun-jaxws.xml?

It’s important to know that missing sun-jaxws.xml basically switches Metro into the Java EE mode. This will allow you to inject webservice instances into servlets and EJB (see JSR 109 spec), but at the same time it will not configure the default JAX-WS servlets. It will be assumed that you will configure your own services.

Building an app

Build your project with mvn package. The actual structure is very simple.

|- WEB-INF
|- classes
    |- ...
|- lib
    |- WEB-INF\lib\webservices-rt-2.3.1.jar 
|- sun-jaxws.xml

Where is my web.xml?

Where did we put the web.xml? Nowhere. As of Servlet 3.0 API, this file is no longer necessary. Metro already supports dynamic servlet registration (see com.sun.xml.ws.transport.http.servlet.WSServletContainerInitializer). In non-Java EE mode (with sun-jaxws.xml), it will automatically create register the default JAX-WS Servlet.

Deploying an app

Deploy an application into your Tomcat 7 and you’re done. Then, just visit the http://localhost:8080/metro-war-demo-0.0.1-SNAPSHOT/date and observe the endpoint metadata description along with the WSDL.

Source code

See novotnyr/metro-war-demo repository on GitHub.

Appendix

Deploying services on older Tomcats and JDKs

On JDK 6 you have to upgrade the JAX-WS API to the latest version via the endorsement mechanism.

Tomcat 6 on JDK 6

Tomcat 6 redirects the Java endorsed directory to lib/endorsed under the Tomcat installation. Put both webservices API and webservices RT in this folder, thus upgrading both API and implementation to the latest 2.2 version.

Metro ZIP file provides Ant buildfiles that assist with the upgrade process, e. g. metro-on-tomcat.xml

Tomcat 7 on JDK 6

Tomcat 6 redirects the Java endorsed directory to endorsed under the Tomcat installation. However, this directory does not exist and you have to create it.

Tomcat 7 on JDK 7

Despite the endorsed mechanism for JAX-WS being no longer available, JDK 7 and 8 has the latest JAX-WS 2.2 API.

Endorsing JAX-WS

When comparing Java 6 Endorsed and Java 7 Endorsed Libraries, JAX-WS is no longer available for the endorsement mechanism.

The actual implementations available in JDK versions:

  • JDK 6

    • JAX-WS 2.0
    • JAXB 2.0
  • JDK 6 Update 4

    • JAX WS 2.1
    • JAXB 2.1
    • WS/Addressing 1.0
  • JDK 7

    • JAX-WS 2.2
      • Java 1.7.0_65
      • JAX-WS RI 2.2.4-b01
  • JDK 8

    • Java 1.8.0_20:
      • JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e

webservices-api-2.3.1 is already included in JDK 7, except some classes from javax.transaction package that belong to Java EE Specification.

5 thoughts on “Deploying JAX-WS Services on Java 7 and Tomcat 7

  1. Votre abonnement place de stationnement en ligne en quelques cliques, réservez votre place de stationnement pas cher.

    comparez et réservez votre place de parking sur tout le réseau Allopark.com le pro du stationnement à faible prix.

  2. Every weekend i used to pay a visit this web page, for the reason that i want enjoyment, for the reason that this this web site conations in fact pleasant funny data too.

Pridaj komentár

Vaša e-mailová adresa nebude zverejnená. Vyžadované polia sú označené *