Why Does My Spring Boot App Behave Differently as JAR vs WAR? Understanding Embedded and External Tomcat

This article explains why a Spring Boot application runs with the configured port when packaged as a JAR using the embedded Tomcat, but switches to Tomcat's default port and context path when deployed as a WAR, and provides step‑by‑step instructions to package and deploy both formats along with historical context and technical differences.

Java Architect Essentials
Java Architect Essentials
Java Architect Essentials
Why Does My Spring Boot App Behave Differently as JAR vs WAR? Understanding Embedded and External Tomcat

The author encountered a strange issue where a Spring Boot project packaged as a JAR runs with the embedded Tomcat on one machine, but when the same project is packaged as a WAR and deployed to an external Tomcat, the port and context path change.

Running a JAR starts the embedded Tomcat, so the application uses the port defined in application.properties (e.g., server.port=8090). Deploying a WAR to an external Tomcat disables the embedded server; the external Tomcat's configuration (default port 8080 and context path based on the WAR name) takes precedence.

Brief historical background: early CGI scripts gave way to Sun's servlet and JSP standards, leading to Java EE and servlet containers like Tomcat. Later, lightweight embedded servers such as Jetty and Undertow emerged, and the micro‑service trend promoted "use JAR, not WAR" to avoid heavyweight containers.

Differences between JAR and WAR

WAR is a web module containing a WEB-INF directory and can be deployed directly to a servlet container.

JAR usually contains only class files and a Main-Class entry, allowing execution via java -jar.

WAR packages a complete web application; JAR is often used for reusable libraries or components.

JAR files are ZIP‑based archives that can also hold signed content and resources.

Key characteristics of JAR

Security : can be digitally signed to verify integrity.

Reduced download time : an applet bundled in a JAR can be downloaded in a single HTTP request.

Compression : reduces storage size.

Platform extensions : Java Extensions Framework uses JARs to add functionality to the core platform.

WAR file is a compressed representation of a complete web application, excluding the root of the web‑application directory hierarchy.

Conditions for building a WAR

Create the correct web‑application directory hierarchy.

Add a WEB-INF directory with classes and lib sub‑directories.

Place servlet class files in WEB-INF/classes and library JARs in WEB-INF/lib.

Put JSP or static HTML files under the context root.

Create a META-INF directory containing a context.xml file.

Packaging a Spring Boot project as a JAR

Create a new Spring Starter Project in the IDE (packaging defaults to jar).

Run mvn clean package in a terminal; the resulting JAR appears in the target directory.

Packaging the same project as a WAR

Add a ServletInitializer class in the same package as the main application.

Modify pom.xml to change <packaging>war</packaging>.

Exclude the embedded Tomcat starter and add dependencies for javax.servlet-api and tomcat-servlet-api with provided scope.

Keep other Spring Boot starters as needed (e.g., spring-boot-starter-web, spring-boot-starter-thymeleaf).

Run mvn clean package again; the generated WAR can be placed in Tomcat's webapps directory and started.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.4.RELEASE</version>
  </parent>
  <groupId>com.example</groupId>
  <artifactId>demo</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <properties>
    <java.version>1.8</java.version>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.tomcat</groupId>
      <artifactId>tomcat-servlet-api</artifactId>
      <version>8.0.36</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
</project>

After building, place the WAR in Tomcat's webapps directory and start Tomcat to run the application.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavamavenSpring BootpackagingTomcatJARWAR
Java Architect Essentials
Written by

Java Architect Essentials

Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.