JAX-WS on Tomcat

Introduction

I was recently tasked with looking into an issue on Embedded Apache Tomcat 8 where a JAX-WS service was installed. It looks like the services were originally written for Java 5 and JAX-WS 2.1. Before making any changes to the existing implementation, I wanted to check on the latest versions and see what might be different and cause a conflict. I know that the JRE includes later versions of JAX-WS and thought that might be the source of the issue. It turns out that it was not. It was something completely different. However, the exploration into how to make JAX-WS work on Embedded Apache Tomcat 8 was still worth publishing.

Embedded Tomcat

I have a number of projects on Github for Apache Tomcat. They can be found in the list below:

The code for our example using JAX-WS will be using a war file with a simple JAX-WS service that returns the current date.

package com.bluelotussoftware.tomcat.embedded;

import java.io.File;
import javax.servlet.ServletException;
import org.apache.catalina.Host;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.startup.Tomcat;

/**
 * An Example Embedded Apache Tomcat with an JAX-WS service 
 *
 * @author John Yeary <jyeary@bluelotussoftware.com>
 * @version 1.0.0
 */
public class Main {

    /**
     * Main method.
     *
     * @param args command line arguments passed to the application. Currently unused.
     * @throws LifecycleException If a life cycle exception occurs.
     * @throws InterruptedException If the application is interrupted while waiting for requests.
     * @throws ServletException If the servlet handling the response has an exception.
     */
    public static void main(String[] args)
            throws LifecycleException, InterruptedException, ServletException {
        Tomcat tomcat = new Tomcat();
        tomcat.setPort(8080);
        tomcat.setBaseDir("target/tomcat");
        Host host = tomcat.getHost();
        host.setAppBase(".");
        host.setAutoDeploy(true);
        host.setDeployOnStartup(true);
        File ws = new File("src/test/resources/simple-jaxws-1.0.0.war");
        tomcat.addWebapp(host, "", ws.getAbsolutePath());
        tomcat.start();
        tomcat.getServer().await();
    }
}

This will start the application when you run it on (http://localhost:8080) and sets the default application to the base directory. It is very simple to setup and use.

SimpleService

The service that is exposed can be found in the simple-jaxws project. It requires a couple of files like sun-javaws.xml and the actual service. Since the application is running on a Servlet 3.0+ based server it does not require a web.xml file.

sun-javaws.xml

<?xml version="1.0" encoding="UTF-8"?>
<endpoints version="2.0" xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime">
  <endpoint implementation="com.bluelotussoftware.example.Simple" name="SimpleService" url-pattern="/*"/>
</endpoints>

Simple.java

package com.bluelotussoftware.example;

import java.util.Date;
import javax.jws.WebMethod;
import javax.jws.WebService;

/**
 * A simple service that returns the current date when called.
 *
 * @author<a href="mailto:jyeary@bluelotussoftware.com">John Yeary</a>
 * @version 1.0.0
 */
@WebService
public class Simple {

    /**
     * This operation returns the current date when it was run.
     *
     * @return current date.
     */
    @WebMethod(operationName = "getCurrentDate")
    public Date getCurrentDate() {
        return new Date();
    }
}

Summary

Implementing a JAX-WS service on embedded Apache Tomcat is simple to do. Using this techique will allow you to write unit tests (integration tests) that can improve your code quality.