Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

You can run a Spring Boot web app with its own embedded Tomcat, or package it as a WAR and deploy it to an external Tomcat server. For the external-container route, use the servlet-based Spring MVC starter, extend SpringBootServletInitializer, configure WAR packaging, and mark the embedded Tomcat dependency as provided. The steps below show how to create and test the app first, then prepare and deploy it.

Choose embedded Tomcat or an external Tomcat server

Spring Boot applications commonly run as self-contained processes with an embedded server such as Tomcat, Jetty, or Undertow. You do not need to install external Tomcat for that model. A WAR is useful when your organization already manages a shared servlet container or requires deployment through its established Tomcat operations process. Spring describes the standalone model in its Spring Boot project overview and the WAR model in its traditional deployment guide.

Choice How it runs Typical fit
Embedded server Run the application directly, commonly as an executable JAR or WAR. Self-contained services where the application process owns its server.
External Tomcat WAR Deploy a WAR to a separately managed servlet container. Shared or centrally managed Tomcat infrastructure.

A supported executable WAR can serve both purposes: it can be run directly and deployed to an external servlet container. Keep the application’s main method if you want that flexibility.

Create and run a servlet-based Spring Boot app

Generate the project

  1. Open Spring Initializr and generate a project using a servlet-stack web starter, such as Spring Web (the spring-boot-starter-web dependency).
  2. Download and extract the project, then import it into an IDE. Spring’s getting-started guide lists Java 17 or later, Maven 3.5 or later or Gradle 7.5 or later, and IDE options including IntelliJ IDEA, Spring Tool Suite, and VS Code. See the Spring Boot guide.
  3. In the generated application’s package, add a controller:
@RestController
class HelloController {
    @GetMapping("/")
    String hello() {
        return "Hello, Tomcat";
    }
}

Spring Quickstart demonstrates the generated application running with embedded Apache Tomcat on localhost:8080; see Spring Quickstart.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Run and verify the app

From the project directory, start it with the wrapper for your build tool:

  • Maven: ./mvnw spring-boot:run
  • Gradle: ./gradlew bootRun

Open http://localhost:8080/. The response should be Hello, Tomcat. Verify this working baseline before changing packaging; it separates application or controller problems from WAR deployment problems.

Prepare the app for external Tomcat

Use the servlet stack, not WebFlux

This workflow is for Spring MVC applications. Spring WebFlux does not strictly depend on the Servlet API and defaults to Reactor Netty, so Spring Boot does not support WAR deployment for WebFlux applications. Choose the servlet-based web starter instead; see Spring’s traditional deployment documentation.

Extend the servlet initializer

Change the main application class to extend SpringBootServletInitializer and override configure. Retain the main method so the app can still be run directly:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
@SpringBootApplication
public class Application extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

The initializer and its configure callback allow the servlet container to bootstrap the Spring application.

Configure Maven for WAR packaging

In pom.xml, set the packaging to WAR and declare the embedded Tomcat starter as provided, because the external container supplies the servlet server:

<packaging>war</packaging>

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-tomcat</artifactId>
  <scope>provided</scope>
</dependency>

Keep the Spring Boot Maven plugin configuration generated for the project so the WAR is packaged in Spring Boot’s supported layout.

Configure Gradle for WAR packaging

For Gradle, apply the WAR plugin and put the Tomcat starter on the provided runtime classpath. Preserve the Spring Boot plugin version generated for your project rather than copying the illustrative version placeholder below:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
plugins {
    id 'org.springframework.boot' version '3.x.x'
    id 'war'
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
}

Spring prefers providedRuntime to compileOnly here because compile-only dependencies are not available on the test classpath. See the traditional deployment guide.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Build, deploy, and test the WAR

  1. Build the artifact with the wrapper: Maven, ./mvnw clean package; Gradle, ./gradlew clean bootWar.
  2. Find the resulting WAR under Maven’s target/ directory or Gradle’s build/libs/.
  3. Deploy the WAR using the procedure for your Tomcat installation. The Manager application, service controls, and deployment directories differ by installation, so follow the instructions for the Tomcat instance you administer.
  4. Test the application using the actual deployed context path. Tomcat commonly derives that path from the WAR filename unless configuration changes it; do not assume the root path is /.

The WAR must target a servlet container compatible with the Spring Boot version used to build it. Spring’s traditional deployment documentation explains the WAR setup; consult the version-specific Spring Boot requirements and your Tomcat documentation before production deployment.

Check Java, Servlet, and Tomcat compatibility

Spring Boot 3 requires Java 17 or later. Spring Boot 3 is based on Spring Framework 6 and aligns with Jakarta Servlet 6 and Tomcat 10, as described in the Spring Boot 3.0 release notes. Those are major-generation facts, not a guarantee that every Boot 3 minor release works with every Tomcat 10 release. Match the exact Spring Boot line to its documented servlet-container requirements and the Tomcat version you operate.

In particular, do not mix an application expecting the Jakarta Servlet APIs with an older container built for the earlier Java EE namespace. Verify compatibility before deployment rather than treating “Tomcat 10” as a complete version check.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Troubleshoot common deployment problems

  • WAR will not start in Tomcat: Confirm the application extends SpringBootServletInitializer, overrides configure, and was built with WAR packaging.
  • Servlet API or server library conflicts: For external deployment, ensure the embedded Tomcat starter is marked provided (provided in Maven or providedRuntime in Gradle), so the WAR does not compete with the container’s servlet implementation.
  • Application returns an error at the expected URL: Check the deployed context path. It may come from the WAR filename or be set by the Tomcat deployment configuration.
  • WebFlux application cannot be deployed as a WAR: This is a stack mismatch, not a packaging typo. Use Spring MVC for this servlet-container deployment model.
  • Java or servlet-class errors: Check the Java runtime used by Tomcat and the exact Boot/Tomcat compatibility requirements; Boot 3 needs Java 17 or newer.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.