[Spring Boot] Traditional Deployment on Apache Tomcat using Spring Boot WAR

Jay Kim
3 min readAug 11, 2023

This article covers how to create a Spring Boot application which can output a war file and how to deploy on Apache Tomcat.

This application is based on Spring Boot version 3 & Java 17 with Apache Tomcat 10. Apache Tomcat 10 can be downloaded from here.

Project Setup

Note that gradle war creates a WAR file which cannot be executed stand alone where as gradle bootWar creates an executable WAR.

plugins {
java
war
id("org.springframework.boot") version "3.1.2"
id("io.spring.dependency-management") version "1.1.2"
}

group = "io.jay"
version = "0.0.1-SNAPSHOT"
apply(plugin = "war")

java {
sourceCompatibility = JavaVersion.VERSION_17
}

repositories {
mavenCentral()
}

dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")
testImplementation("org.springframework.boot:spring-boot-starter-test")
}

tasks.withType<Test> {
useJUnitPlatform()
}

tasks.war {
archiveFileName.set("service.war")
}

Implementation

Note that the main class has to extend SpringBootServletInitializer and configure() is overridden.

package io.jay.service;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@SpringBootApplication
public class MainApplication extends SpringBootServletInitializer {

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

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

@Controller
class TomcatController {

@GetMapping("/")
public String index() {
return "index.html";
}
}

@Controller
@ResponseBody
class HelloController {
@GetMapping("/hello")
public String hello() {
return "Hello there !";
}
}

Let us create index file for fun.index.html is placed under src/main/resources/static:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Document</title>
</head>
<body>
<h1>Hello</h1>
</body>
</html>

Building and Deploying

Let us build a WAR file using gradle war command. This will output service.war where service is the name of this application. I downloaded and extracted Tomcat under ~/Downloads/apache-tomcat-10.1.11. This will be my Tomcat path.

Copy the WAR file and place under ~/Downloads/apache-tomcat-10.1.11/webapps.

service.war is placed under webapps directory

When I first downloaded and extracted Tomcat, all the executable files did not have permission to be executed.

cd ~/Downloads/apache-tomcat-10.1.11

# to start up Tomcat
chmod +x bin/catalina.sh
chmod +x bin/startup.sh

# to shut down Tomcat
chmod +x bin/shutdown.sh

Start Tomcat by running ~/Downloads/apache-tomcat-10.1.11/bin/startup.sh script.

Output of startup script

There will be a service directory once Tomcat is started.

service directory is created automatically

The Spring Boot application will be served under http://localhost:8080/service.

Tomcat returning index.html
Tomcat returning /hello endpoint

--

--