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 { mavenCentral() } 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> <html> <body> hello, world </body> </html> |
The src/main/java/com/jamesward/WebConfig.java file uses Spring annotations to configure Spring MVC:
package com.jamesward; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.*; @Configuration @EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/**").addResourceLocations("classpath:/assets/"); } @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("redirect:index.html"); } } |
Finally, a simple “static void main” Java class is used to start Jetty. The src/main/java/com/jamesward/Webapp.java 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.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.servlet.DispatcherServlet; public class Webapp { public static void main(String[] args) throws Exception { final AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext(); applicationContext.register(WebConfig.class); final ServletHolder servletHolder = new ServletHolder(new DispatcherServlet(applicationContext)); final ServletContextHandler context = new ServletContextHandler(); context.setContextPath("/"); context.addServlet(servletHolder, "/*"); String webPort = System.getenv("PORT"); if (webPort == null || webPort.isEmpty()) { webPort = "8080"; } final Server server = new Server(Integer.valueOf(webPort)); server.setHandler(context); server.start(); server.join(); } } |
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.

Pingback: Breaking Free From Containers | Dynacron Group
Pingback: SpringMVC with Embedded Jetty | jasonish
Pingback: SpringMVC with Embedded Jetty « jasonish