What You’ll Create

A WAR application which will contain Javalin without Jetty. You can drop this WAR file into any Servlet 3.0 container.

Getting Started

The easiest way to get started is to clone the javalin-tomcat-embed-example example application:

git clone https://github.com/tipsy/javalin-tomcat-embed-example
cd javalin-tomcat-embed-example
./gradlew clean appRun

This will run Gradle Gretty plugin which in turn launches this WAR app in Tomcat. When the server boots, you can access the REST endpoint simply by typing this in your terminal, or opening http://localhost:8080/rest :

curl localhost:8080/rest/

Looking At The Sources

The project is using Gradle to do standard stuff: declare the project as WAR and uses the Gradle Gretty Plugin to easily launch the WAR app in Tomcat (using the appRun task).

The interesting bit is the dependencies stanza which includes Javalin but omits the Jetty dependency:

dependencies {
    compile(kotlin("stdlib-jdk8"))
    compile("io.javalin:javalin:3.13.13") {
        exclude(mapOf("group" to "org.eclipse.jetty"))
        exclude(mapOf("group" to "org.eclipse.jetty.websocket"))
    }
    compile("org.slf4j:slf4j-simple:1.7.30")
}

The servlet itself is very simple:

@WebServlet(urlPatterns = ["/rest/*"], name = "MyRestServlet", asyncSupported = false)
class MyRestServlet : HttpServlet() {
    val javalin: JavalinServlet = Javalin.createStandalone()
            .get("/rest") { ctx -> ctx.result("Hello!") }
            .servlet()

    override fun service(req: HttpServletRequest, resp: HttpServletResponse) {
        javalin.service(req, resp)
    }
}

Note: You must remember to use the createStandalone() function, which has been carefully designed to make Javalin not to depend on Jetty. Using Javalin.create() will make the WAR app fail to start with java.lang.ClassNotFoundException: org.eclipse.jetty.server.Server.

The Servlet container will automatically auto-discover the servlet (since it’s annotated with @WebServlet); any requests to the servlet will be directed straight to Javalin which will then take care of handling the request properly. Annotate your class with @MultipartConfig in order to populate UploadedFile or UploadedFiles servlet-request getters.