Spring Boot - How to Create a Deployable War

Spring boot, by default, enables you to create standalone applications through simple, minimal configurations. And due to its self-contained nature, it naturally enables building microservices.

Spring starters are poms (if using maven) that
encapsulate all the required dependencies that you need to start building an application. And for web applications, it is spring-boot-starter-web. It not only enables Spring MVC and other web components but also injects an embedded tomcat server by default.


<dependency>
  <groupid>org.springframework.boot</groupid>
  <artifactid>spring-boot-starter-web</artifactid>
</dependency>
 

But, what if you do not want to couple your application to a single container, and instead want to create a distributable war and not a standalone fat jar. The following steps would help.

First and foremost, change the packaging of the pom to war.


<groupid>com.codelooru</groupid>
<artifactid>MyWebApp</artifactid>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>


Next, add the spring-boot-starter-tomcat dependency and set the scope to provided. This would remove the spring-boot-starter-tomcat dependency from the war and decouple the application from tomcat.


<dependency>
   <groupid>org.springframework.boot</groupid>
   <artifactid>spring-boot-starter-tomcat</artifactid>
   <scope>provided</scope>
</dependency>


Then you define a ServletInitializer by extending the SpringBootServletInitializer, as shown below. This would initialize the container's ServletContext with the Servlets and Filters from the Spring application context.

import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;

public class MyWebAppServletInitializer extends SpringBootServletInitializer {

 @Override
 protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
  return builder.sources(MyWebAppApplication.class);
 }

}


MyWebAppApplication in the example above is your Spring Boot Application class.

That's it. Now, when you build the application, you would get a nice deployable war.

An easier way ... 


Spring Initializr does all of the above when you choose the packaging as war. So, if you are clear from the very onset that you want to generate deployable wars, then use this option instead.