Containerless Spring MVC

Many of the new JVM-based web frameworks are ditching containers and WAR files and instead using a WAR-less / Containerless approach. But that doesn’t mean you have to ditch your favorite Java web framework. A while back I posted about going containerless with Tapestry. Now lets do the same with Spring MVC. You can grab the full source code from GitHub.

First we need a build that defines the dependencies. Here is the build.gradle file for my Gradle build:

apply plugin:'java'
apply plugin:'application'
version = '0.0.1-SNAPSHOT'
mainClassName = "com.jamesward.Webapp"
applicationName = "webapp"
repositories {
dependencies {
    compile 'org.springframework:spring-webmvc:3.1.2.RELEASE'
    compile 'cglib:cglib:2.2.2'
    compile 'org.eclipse.jetty:jetty-webapp:8.1.5.v20120716'

There isn’t much to this build except a few dependencies: Spring MVC, CGLib, and Jetty.

The src/main/resources/assets/index.html file just contains simple HTML:

<!doctype html>
hello, world

The src/main/java/com/jamesward/ file uses Spring annotations to configure Spring MVC:

package com.jamesward;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;
public class WebConfig extends WebMvcConfigurerAdapter {
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
    public void addViewControllers(ViewControllerRegistry registry) {

Finally, a simple “static void main” Java class is used to start Jetty. The src/main/java/com/jamesward/ file just sets up the HTTP listener and starts it:

package com.jamesward;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.springframework.web.servlet.DispatcherServlet;
public class Webapp {
    public static void main(String[] args) throws Exception {
        final AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
        final ServletHolder servletHolder = new ServletHolder(new DispatcherServlet(applicationContext));
        final ServletContextHandler context = new ServletContextHandler();
        context.addServlet(servletHolder, "/*");
        String webPort = System.getenv("PORT");
        if (webPort == null || webPort.isEmpty()) {
            webPort = "8080";
        final Server server = new Server(Integer.valueOf(webPort));

That’s it! To build and run this project locally you can simple run:

./gradlew run

(Note: Run “gradlew.bat” on Windows.)

So simple it’s hard to believe it works. :) Let me know if you have any questions.

  • Look at you, Mr. here’s my sinatra equivalent for Java. That’s pretty fancy.

  • WAR-less, yes, but isn’t Jetty a container?

    • I guess it depends on how you define “container”. I usually think of a container as something you deploy into. In this case Jetty is part of the application, not an external thing.

  • ugo

    we can do that with Netty for example ?

    • I haven’t tried doing this with Netty because Spring MVC uses the Servlet API which doesn’t work well with NIO.

  • nhwind

    Awesome! Thanks. Would love to see a development set up in Eclipse using jrebel or alike..

  • arhan

    This is not really “containerless”, isn’t it? :) That’s just an embedded Jetty, which is still a container

    • It depends on how you define “containerless”. See the comment below. How would you define “containerless”?

      • arhan

        “Containerless”, in this context, I’d define as the “one that doesn’t implement JEE spec, i.e. not a servlet container. For instance, a netty/mina/vert.x based implementation would qualify as “containerless”

        • I definitely agree that Play, Vert.x, etc are containerless. But I wouldn’t say that if an app uses the Servlet API that it can’t be containerless. This example may not be 100% containerless, but it’s probably as close as you can get with the Servlet API.

          • arhan

            OK! I agree :)

  • Ian Durkan

    A nice demo, but interestingly enough this did not build on my system without further tweaking due to an issue in Gradle that prevents a dependency org.eclipse.jetty.orbit from downloading. See here for more information about a work-around.

    • That is odd. I wonder why it worked for me. Are you using Gradle 1.1 or the gradlew from my source?

      • Ian Durkan

        As it turns out, I still had Gradle 1.0 on the VM where I was trying to build. Oops!

        • Cool. Glad it was something simple. :)

  • Pingback: Breaking Free From Containers | Dynacron Group()

  • Jason

    I’ve been deploying spring mvc like this for a while now. But JSPs are always a problem, and they are somewhat core to spring mvc.

  • Pingback: SpringMVC with Embedded Jetty | jasonish()

  • Pingback: SpringMVC with Embedded Jetty « jasonish()

  • deepak

    how can we add a view resolver in this setup of server ?

    • You should be able to do anything with this setup that you can do normally.

  • renanleandrof

    But what if i’m using .xml to load my app?
    Can you help me to run this with my applicationContext.xml instead of the class??


    • That should work just fine. Maybe put the applicationContext.xml into the src/main/resources dir?