JAX-RS (using Apache CXF) in embedded Tomcat example

January 13, 2015 [Java, rest, Tech]

I had serious trouble today firing up an embedded Tomcat server that serves up REST resources using JAX-RS via Apache CXF.

Here's minimal example, hopefully saving you the same trouble:

src/HelloJaxRs.java:

import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.Context;
import org.apache.catalina.Wrapper;

public class HelloJaxRs
{
    public static void main( String[] args ) throws Exception
    {
        Tomcat tomcat = new Tomcat();
        Context context = tomcat.addContext( "/", "" );

        Wrapper servlet = context.createWrapper();
        servlet.setName( "jaxrs" );
        servlet.setServletClass(
            "org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet" );

        servlet.addInitParameter(
            "jaxrs.serviceClasses",
            Hello.class.getName()
        );

        servlet.setLoadOnStartup( 1 );
        context.addChild( servlet );
        context.addServletMapping( "/rest/*", "jaxrs" );

        tomcat.start();
        tomcat.getServer().await();
    }
}

src/Hello.java:

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;

@Path( "/hello/{name}" )
public class Hello
{
    @GET
    public String getThing( @PathParam( "name" ) String name )
    {
        return "Hello, " + name;
    }
}

build.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project default="run">

&lt;target name="run" depends="compile"&gt;
    &lt;mkdir dir="bin/tomcat.8080/webapps"/&gt;
    &lt;java
        classname="HelloJaxRs"
        fork="true"
        failonerror="true"
        dir="bin"
    &gt;
        &lt;classpath&gt;
            &lt;pathelement location="bin/"/&gt;
            &lt;fileset dir="lib"&gt;&lt;include name="**/*.jar"/&gt;&lt;/fileset&gt;
        &lt;/classpath&gt;
    &lt;/java&gt;
&lt;/target&gt;

&lt;target name="compile"&gt;
    &lt;mkdir dir="bin"/&gt;
    &lt;javac srcdir="src" destdir="bin"&gt;
        &lt;classpath&gt;
            &lt;fileset dir="lib"&gt;&lt;include name="**/*.jar"/&gt;&lt;/fileset&gt;
        &lt;/classpath&gt;
        &lt;compilerarg value="-Werror"/&gt;
    &lt;/javac&gt;
&lt;/target&gt;

</project>

To download the dependencies (or you can do something clever with Maven):

$ mkdir lib
$ cd lib
$ wget http://www.webhostingjams.com/mirror/apache/tomcat/tomcat-7/v7.0.57/bin/apache-tomcat-7.0.57.tar.gz
$ tar -xzf apache-tomcat-7.0.57.tar.gz
$ wget http://www.apache.org/dyn/closer.cgi?path=/cxf/3.0.3/apache-cxf-3.0.3.tar.gz
$ tar -xzf apache-cxf-3.0.3.tar.gz
$ cd ..

To run Tomcat:

$ ant

Then, in another terminal, you can see it's working:

$ curl http://localhost:8080/rest/hello/andy
Hello, andy