WEB-INF not included in WebApp using SpringBoot, Spring-MVC and Maven
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
If you have worked with traditional Java web applications, you are accustomed to the WEB-INF directory sitting at the root of your WAR file and holding web.xml, JSP files, and library JARs. When you create a new Spring Boot project with Spring MVC and Maven, that directory is nowhere to be found. This is not a bug; it is a deliberate design choice that reflects how Spring Boot packages and runs applications.
Why WEB-INF Exists in Traditional WAR Projects
In a classic Servlet-based application deployed to an external server like Tomcat or Jetty, WEB-INF serves several purposes.
The Servlet specification states that files under WEB-INF are not directly accessible by a client browser, which makes it a safe place to store JSPs and configuration. The web.xml deployment descriptor defines servlets, filters, and listener mappings. The lib folder holds third-party JARs, and classes holds compiled bytecode.
How Spring Boot Changes the Picture
Spring Boot defaults to packaging your application as an executable JAR (not a WAR). An executable JAR uses an embedded Tomcat, Jetty, or Undertow server, so there is no external Servlet container to deploy into. Because there is no external container, there is no need for WEB-INF or web.xml. Spring Boot replaces web.xml with auto-configuration and Java-based configuration classes.
Maven's spring-boot-maven-plugin repackages the JAR with the embedded server and all dependencies inside it. The resulting artifact is self-contained.
Adding JSP Support with WEB-INF
If you still need JSPs, perhaps because you are migrating a legacy application, you can bring WEB-INF back. Create the directory manually under src/main/webapp.
Then configure the view resolver in application.properties so Spring MVC knows where to find JSP files.
You also need to add the Tomcat JSP dependency and switch your packaging from JAR to WAR in pom.xml.
Finally, make your main class extend SpringBootServletInitializer so it works both as a standalone JAR (with embedded Tomcat) and as a WAR deployed to an external server.
When to Use Templates Instead
Spring Boot strongly encourages server-side template engines like Thymeleaf, FreeMarker, or Mustache over JSPs. Templates are loaded from the classpath (src/main/resources/templates/), which means they work with JAR packaging out of the box and do not require WEB-INF at all.
This approach is simpler, faster to develop with (templates support hot-reload), and fully compatible with executable JAR packaging.
Common Pitfalls
- Placing JSPs under src/main/resources: JSPs must live under
src/main/webapp/WEB-INF, not on the classpath. The embedded Tomcat JSP engine cannot find them fromresources/. - Forgetting to change packaging to WAR: If you add
src/main/webapp/WEB-INFbut leave\<packaging>jar\</packaging>in your POM, Maven ignores thewebappdirectory entirely during the build. - Missing tomcat-embed-jasper dependency: Without this dependency, the embedded Tomcat has no JSP compiler. Requests to JSP-backed endpoints return a 404 or a blank page with no helpful error message.
- Not extending SpringBootServletInitializer: If you package as WAR and deploy to an external Tomcat without this class, the container does not know how to bootstrap your Spring context.
- Using WEB-INF out of habit: Many developers add
WEB-INFto a Spring Boot project simply because they are used to it. Unless you have a concrete need for JSPs, prefer Thymeleaf or another template engine, which avoids the complexity of WAR packaging altogether.
Summary
- Spring Boot packages applications as executable JARs with an embedded server, eliminating the need for
WEB-INFandweb.xml. - If you need JSPs, create
src/main/webapp/WEB-INF, switch Maven packaging to WAR, and add thetomcat-embed-jasperdependency. - Extend
SpringBootServletInitializerto support deployment to both embedded and external Servlet containers. - For new projects, prefer Thymeleaf or FreeMarker templates stored in
src/main/resources/templates/, which work seamlessly with JAR packaging. - The absence of
WEB-INFis intentional and reflects Spring Boot's philosophy of convention over configuration and self-contained deployable artifacts.

