151

I have a simple Spring Boot application that gets messages from a JMS queue and saves some data to a log file, but does not need a web server. Is there any way of starting Spring Boot without the web server?

Ilja Everilä
  • 50,538
  • 7
  • 126
  • 127
Michael
  • 13,838
  • 18
  • 52
  • 81
  • 3
    If you don't need web then don't include it, when not included the embedded server will not start. You would only need the starter parent and add `spring-jms` (I guess) as a dependency. Then just start the application, no server will be started. – M. Deinum Sep 30 '14 at 05:57
  • see http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#build-tool-plugins-maven-packaging – Thomas Mar 03 '15 at 20:46
  • 3
    You are wrong, I use only spring-boot-starter-batch, I do not include any tomcat or other server config in my pom.xml, however executing the application launches a web container. It must take a parameter somewhere. – Mehdi Aug 30 '17 at 19:32

17 Answers17

163

Spring Boot 2.x, 3.x

  • Application Properties

      spring.main.web-application-type=NONE 
      # REACTIVE, SERVLET
    
  • or SpringApplicationBuilder

      @SpringBootApplication
      public class MyApplication {
    
          public static void main(String[] args) {
              new SpringApplicationBuilder(MyApplication.class)
                  .web(WebApplicationType.NONE) // .REACTIVE, .SERVLET
                  .run(args);
         }
      }
    

Where WebApplicationType:

  • NONE - The application should not run as a web application and should not start an embedded web server.
  • REACTIVE - The application should run as a reactive web application and should start an embedded reactive web server.
  • SERVLET - The application should run as a servlet-based web application and should start an embedded servlet web server.
kinjelom
  • 6,105
  • 3
  • 35
  • 61
156

if you want to run Spring Boot 1.x without a servlet container, but with one on the classpath (e.g. for tests), use the following, as described in the spring boot documentation:

@Configuration
@EnableAutoConfiguration
public class MyClass {
    public static void main(String[] args) throws JAXBException {
         SpringApplication app = new SpringApplication(MyClass.class);
         app.setWebEnvironment(false); //<<<<<<<<<
         ConfigurableApplicationContext ctx = app.run(args);
    }
}

also, I just stumbled across this property:

spring.main.web-environment=false
kinjelom
  • 6,105
  • 3
  • 35
  • 61
Stefan K.
  • 7,701
  • 6
  • 52
  • 64
57

You can create something like this:

@SpringBootApplication
public class Application {
  public static void main(String[] args) {
    new SpringApplicationBuilder(Application.class).web(false).run(args);
  }
}

And

@Component
public class CommandLiner implements CommandLineRunner {

  @Override
  public void run(String... args) throws Exception {
    // Put your logic here
  }

}

The dependency is still there though but not used.

sancho21
  • 3,511
  • 1
  • 39
  • 45
  • Can we safely remove sprign-boot-starter-web dependency ? For now making app non-web and removing this dependency causes exception ClassNotFound: javax.servlet.ServleContext – Simon Logic Nov 27 '18 at 10:51
  • Please note, solution 1 is deprecated – ACV Apr 01 '19 at 09:54
27

Spring boot will not include embedded tomcat if you don't have Tomcat dependencies on the classpath. You can view this fact yourself at the class EmbeddedServletContainerAutoConfiguration whose source you can find here.

The meat of the code is the use of the @ConditionalOnClass annotation on the class EmbeddedTomcat


Also, for more information check out this and this guide and this part of the documentation

geoand
  • 60,071
  • 24
  • 172
  • 190
  • In its current version, the `gs-convert-jar-to-war/complete` Maven project *does* add an embedded Tomcat server, despite the `spring-boot-starter-tomcat` dependency declared with scope `provided`. This feels like a bug. Also see http://stackoverflow.com/q/25991789/923560 – Abdull Oct 26 '14 at 23:25
12

The simplest solution. in your application.properties file. add the following property as mentioned by a previous answer:

spring.main.web-environment=false

For version 2.0.0 of Spring boot starter, use the following property :

spring.main.web-application-type=none

For documentation on all properties use this link : https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html

Mehdi
  • 1,340
  • 15
  • 23
12

Use this code.

SpringApplication application = new SpringApplication(DemoApplication.class);
application.setWebApplicationType(WebApplicationType.NONE);
application.run(args);
nayun oh
  • 121
  • 1
  • 2
  • With Spring Boot v2.4.4, Spring v5.3.5 this solution worked. I tried setting the following properties (not together, one at a time) but none of them worked: spring.main.web-application-type=NONE, spring.main.web_environment=false, spring.main.web-environment-type=none, spring.main.web-environment=false. I know the properties were being read because I could read them from main(...), and I could also change the port number using the same properties file. – ssimm Aug 24 '21 at 15:35
11

For Spring boot v2.1.3.RELEASE, just add the follow properties into application.propertes:

spring.main.web-application-type=none
Chun Hau Lai
  • 129
  • 1
  • 2
10

If you need web functionality in your application (like org.springframework.web.client.RestTemplate for REST calls) but you don't want to start a TOMCAT server, just exclude it in the POM:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>
Paul Rambags
  • 639
  • 7
  • 5
6
  • Through program :

    ConfigurableApplicationContext ctx =  new  SpringApplicationBuilder(YourApplicationMain.class)
    .web(WebApplicationType.NONE)
    .run(args);
    
  • Through application.properties file :

    spring.main.web-environment=false 
    
  • Through application.yml file :

    spring:
     main:
      web-environment:false
    
5

Spring boot has many starters, some starters have an embedded web server, some don't. The following have the embedded web server:

spring-boot-starter-web
spring-boot-starter-data-jpa
spring-boot-starter-jetty
spring-boot-starter-tomcat
spring-boot-starter-jdbc
spring-boot-starter-data-rest
...

Pick the one that meets your requirements and that does not have server support.

I only need to make restful json api request in my spring application, so the starter I need is

spring-boot-starter-json

which provide RestTemplate and jackson for me to use.

Cummings
  • 128
  • 2
  • 13
alijandro
  • 11,627
  • 2
  • 58
  • 74
4

You can use the spring-boot-starter dependency. This will not have the web stuff.

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter</artifactId>
</dependency>
Roland
  • 607
  • 1
  • 7
  • 12
3

In Spring boot, Spring Web dependency provides an embedded Apache Tomcat web server. If you remove spring-boot-starter-web dependency in the pom.xml then it doesn't provide an embedded web server.

remove the following dependency

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
</dependency>
Arghya Sadhu
  • 41,002
  • 9
  • 78
  • 107
Zakib Ali
  • 81
  • 1
  • 3
2

If you want to use one of the "Getting Started" templates from spring.io site, but you don't need any of the servlet-related stuff that comes with the "default" ("gs/spring-boot") template, you can try the scheduling-tasks template (whose pom* contains spring-boot-starter etc) instead:

https://spring.io/guides/gs/scheduling-tasks/

That gives you Spring Boot, and the app runs as a standalone (no servlets or spring-webmvc etc are included in the pom). Which is what you wanted (though you may need to add some JMS-specific stuff, as someone else points out already).

[* I'm using Maven, but assume that a Gradle build will work similarly].

2

Remove folowing dependancy on your pom file will work for me

  <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
vaquar khan
  • 10,864
  • 5
  • 72
  • 96
2

For Kotling here is what I used lately:


// src/main/com.blabla/ShellApplication.kt

/**
 * Main entry point for the shell application.
 */
@SpringBootApplication
public class ShellApplication : CommandLineRunner {
    companion object {
        @JvmStatic
        fun main(args: Array<String>) {
            val application = SpringApplication(ShellApplication::class.java)
            application.webApplicationType = WebApplicationType.NONE
            application.run(*args);
        }
    }

    override fun run(vararg args: String?) {}
}

// src/main/com.blabla/command/CustomCommand.kt

@ShellComponent
public class CustomCommand {
    private val logger = KotlinLogging.logger {}

    @ShellMethod("Import, create and update data from CSV")
    public fun importCsv(@ShellOption() file: String) {
        logger.info("Hi")
    }
}

And everything boot normally ending up with a shell with my custom command available.

Vincent
  • 452
  • 1
  • 7
  • 20
2

From my experience on spring boot > 2.5 ,

  • if you plan to build the application as a jar file, in my opinion the solution of spring.main.web-application-type=NONE should not be widely accepted and used, since it has only a limited scope of benefits.

    For asking to have spring boot without the web server, it means that you have from Spring either the dependency spring-boot-starter-web to build a spring web application or the dependency spring-boot-starter-jersey to build a jax-rs web application. Those dependencies pack inside the spring-boot-starter-tomcat which will then bring the dependency of tomcat-embed-core which is the actual tomcat server. This library is packed automatically inside and is of size ~3.3 MB. Even if you disable the server with the aforementioned property, you will still deliver your application jar file, containing the tomcat server inside.

    So the con of just using the aforementioned property is that the deliverable jar file will be some MB larger in size without any actual need.

    So if you want to have spring boot without the web server just don't use the dependencies spring-boot-starter-jersey or spring-boot-starter-web since if you build your application as a jar file there is no reason to have those dependencies and not have an embedded server delivered.

  • if you plan to build the application as a war file, you should also not use the above property. In this case you will just need in your .pom the following configurations

    <packaging>war</packaging>
    
        <dependencies>
          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-web or (spring-boot-starter-jersey)</artifactId>
              <exclusions>
                  <exclusion>
                      <groupId>org.springframework.boot</groupId>
                      <artifactId>spring-boot-starter-tomcat</artifactId>
                  </exclusion>
              </exclusions>
          </dependency>
          <dependency>
              <groupId>javax.servlet</groupId>
              <artifactId>javax.servlet-api</artifactId>
              <version>pick the version that the server that already runs in production supports</version>
              <scope>provided</scope>
          </dependency>
       </dependencies>
    
  • Exceptional cases

    The property spring.main.web-application-type=NONE should be in my opinion used for some exceptional cases like if we build some web library that needs the above dependencies but is not to be used like a web application, or we have some complex type of testing that needs those libraries although the application does not need any server to run. This type of usages are however rare.

Panagiotis Bougioukos
  • 15,955
  • 2
  • 30
  • 47
0

Similar to @nayun oh answer above, but for older versions of Spring, use this code:

SpringApplication application = new SpringApplication(DemoApplication.class);
application.setApplicationContextClass(AnnotationConfigApplicationContext.class);
application.run(args);
Chris Wolf
  • 1,539
  • 2
  • 10
  • 9