Enable or Disable Embedded Tomcat in Spring Boot Using Profiles
In many Spring Boot applications, especially those that support multiple deployment modes, it is common to encounter different runtime environments. For instance, one mode might expose a RESTful API using an embedded Tomcat server, while another might rely purely on messaging (e.g., using JMS or Kafka) without needing any HTTP layer.
In this article, we will explore how to conditionally enable or disable the embedded Tomcat server in Spring Boot using Spring Profiles.
1. How Embedded Tomcat Works in Spring Boot
Spring Boot simplifies web application development by including embedded servlet containers, with Tomcat as the default. This means we don’t need to deploy your application to an external application server. Instead, the application becomes a self-contained JAR that starts its own web server upon running.
1.1 Why Embedded Tomcat?
- Convenience: No need to install or manage Tomcat separately.
- Portability: Run your application anywhere Java is available.
- Control: You can easily configure or exclude web server behavior using Spring Boot’s auto-configuration features.
By default, including spring-boot-starter-web pulls in the necessary dependencies to auto-configure Tomcat and start it on a specified port (default is 8080). However, this can be problematic in applications where not all profiles require a web layer. For example, background processing applications using JMS or scheduled jobs.
That is where conditional configuration and profile-specific loading come in, allowing us to enable or disable embedded Tomcat as needed.
2. Problem Statement
Imagine we are building a Spring Boot application that serves different functions depending on the active profile:
- Under the “http” profile, it starts a REST server using Spring MVC and an embedded Tomcat.
- Under the “jms” profile, it listens to JMS queues, and a web server is not needed.
Normally, including the spring-boot-starter-web dependency will cause Spring Boot to auto-configure an embedded web server (like Tomcat) and start it regardless of the active profile. This is undesirable when running in a non-web context.
To prevent Spring Boot from loading the embedded web server by default, we need to set spring.main.web-application-type=none for non-web profiles, ensuring Tomcat is only initialized when explicitly enabled through a profile-specific configuration.
3. Profile-Specific Configurations
HTTP Profile – Enable Embedded Tomcat and REST Controller
Below, we define a configuration that only activates when the http profile is selected.
@Profile("http")
@Configuration
@RestController
public class HttpServerConfig {
@GetMapping("/hello")
public String sayHello() {
return "Hello from HTTP profile!";
}
}
JMS Profile – No Web Server
In the jms profile, we define a listener for JMS messages. No REST controllers are needed here.
@Profile("jms")
@Configuration
@EnableJms
public class JmsConfig {
@JmsListener(destination = "input.queue")
public void listen(Message message) {
try {
if (message instanceof TextMessage textMessage) {
System.out.println("Received JMS message: " + textMessage.getText());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
This configuration handles JMS messages and does not need any web layer or Tomcat server to run.
4. Configuring Spring Boot Profiles
Spring Boot uses profiles to activate a specific set of configurations. Profiles can be set in several ways:
4.1 Example Configuration for Different Profiles
application-http.properties
server.port=8080 spring.main.web-application-type=servlet
application-jms.properties
spring.main.web-application-type=none
Spring Boot automatically loads these based on the active profile set via spring.profiles.active.
application.properties
This is the default location to configure the active profile and application behavior.
spring.profiles.active=jms spring.main.web-application-type=none
This config ensures that no web context is initialized when using the jms profile.
5. Testing the Profiles
Running with JMS Profile
To run without starting Tomcat:
mvn spring-boot:run -Dspring-boot.run.profiles=jms
Output:
2025-05-21T16:31:23.556+01:00 INFO 48065 --- [conditional-tomcat] [ main] c.j.e.ConditionalTomcatApplication : The following 1 profile is active: "jms" 2025-05-21T16:31:25.981+01:00 INFO 48065 --- [conditional-tomcat] [ main] c.j.e.config.JmsConfiguration : JMS configuration initialized 2025-05-21T16:31:26.210+01:00 INFO 48065 --- [conditional-tomcat] [ main] c.j.e.service.MessageListenerService : Received JMS message: "Hello from JMS!" 2025-05-21T16:31:39.475+01:00 INFO 48065 --- [conditional-tomcat] [ main] c.j.e.ConditionalTomcatApplication : Started ConditionalTomcatApplication in 18.394 seconds (process running for 20.621)
The active profile is confirmed as “jms“, and the application starts up successfully without initializing embedded Tomcat, resulting in no Tomcat-related logs being displayed.
Running with HTTP Profile
To run the application with the http profile:
mvn spring-boot:run -Dspring-boot.run.profiles=http
Output:
When the “http” profile is active, the application starts successfully with embedded Tomcat initialized, and Tomcat-related logs are displayed, confirming that the web server is up and ready to serve HTTP requests.
Accessing http://localhost:8080/hello returns:
Hello from HTTP profile!
6. Conclusion
In conclusion, by leveraging Spring Boot profiles and the spring.main.web-application-type property, you can enable or disable embedded Tomcat as needed. This approach ensures your application only starts a web server when required, keeping it lightweight and tailored to specific runtime needs.
7. Download the Source Code
This article explored how to enable or disable embedded Tomcat in Spring Boot based on active profiles.
You can download the full source code of this example here: spring boot enable disable embedded tomcat





