27

Spring boot non-web application, when start it has below error

Caused by: org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getEmbeddedServletContainerFactory(EmbeddedWebApplicationContext.java:185) ~[spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE]

Then I tried below manner

new SpringApplication().setWebEnvironment(false);

then start it still have above error.

Then tried

@SpringBootApplication(exclude={SpringDataWebAutoConfiguration.class})

but still have the same error.

At last I tried add below configuration in application.properties

spring.main.web-environment=false

this time it works.

Why the first two manner cannot work?

zhuguowei
  • 8,401
  • 16
  • 70
  • 106
  • 1
    Post the actual code not a snippet... There are more lines in your `main` method. So post the application class. – M. Deinum May 12 '16 at 13:11
  • Try this `@SpringBootApplication(exclude = {EmbeddedServletContainerAutoConfiguration.class, WebMvcAutoConfiguration.class})` as [Suggested here](http://stackoverflow.com/questions/32078015/spring-boot-enable-disable-embedded-tomcat-with-profile) – Sanjay Rawat May 13 '16 at 20:18
  • @SanjayRawat still not work, please see https://github.com/zhugw/spring-boot-disable-web-environment – zhuguowei May 14 '16 at 06:18
  • @M.Deinum please see https://github.com/zhugw/spring-boot-disable-web-environment – zhuguowei May 14 '16 at 06:18

4 Answers4

60

Starting from Spring Boot 2.0

-web(false)/setWebEnvironment(false) is deprecated and instead Web-Application-Type can be used to specify

  • Application Properties

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

    @SpringBootApplication
    public class SpringBootDisableWebEnvironmentApplication {
    
        public static void main(String[] args) {
            new SpringApplicationBuilder(SpringBootDisableWebEnvironmentApplication.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.

Courtesy: Another SO Answer

Narasimha
  • 1,537
  • 1
  • 16
  • 17
  • Thanks for pointing to a Spring Boot 2 solution; I was looking for a migration from Spring 1. – рüффп Jan 28 '19 at 07:39
  • In your example, it's not clear where I would put code to handle the arguments passed to the `run()` method. It's also not clear where I put my application code. – MiguelMunoz Dec 03 '22 at 05:39
7

This answer is obsolete. Please note the other answer for Spring Boot 2.0

Original answer for Spring Boot 1.x:

The reason this config is not working because these are two different instances:

new SpringApplication().setWebEnvironment(false); 
SpringApplication.run(SpringBootDisableWebEnvironmentApplication.class, args);

You are disabling setWebEnvironment(false) in new SpringApplication() object and calling static method run() on SpringApplication.run(...) which is different one.

I figured out 3 ways to do this:

@SpringBootApplication
public class SpringBootDisableWebEnvironmentApplication implements CommandLineRunner{


    public static void main(String[] args) throws Exception {

//      Method#1: Using SpringApplicationBuilder.

        SpringApplication springApplication = 
                new SpringApplicationBuilder()
                .sources(SpringBootDisableWebEnvironmentApplication.class)
                .web(false)
                .build();

        springApplication.run(args);

//--------------------------------------------------------      

//      Method#2: Using SpringBootDisableWebEnvironmentApplication.     

//      SpringBootDisableWebEnvironmentApplication springBootDisableWebEnvironmentApplication = 
//              new SpringBootDisableWebEnvironmentApplication();
//      springBootDisableWebEnvironmentApplication.run(args);

//--------------------------------------------------------      

//      Method#3: Using SpringApplication().

//      SpringApplication springApplication = new SpringApplication();
//      springApplication.setWebEnvironment(false);
//      
//      Set<Object> sources = new HashSet<>();
//      sources.add(SpringBootDisableWebEnvironmentApplication.class);
//      springApplication.setSources(sources);
//      springApplication.run(args);

//--------------------------------------------------------  

    }

    @Override
    public void run(String... arg0) throws Exception {
        System.out.println("Hello, Spring Boot gives many options ;)");
    }
}

Here is the complete working Project.

And you don't need to exclude below config:

@SpringBootApplication(exclude = {EmbeddedServletContainerAutoConfiguration.class, 
                              WebMvcAutoConfiguration.class})

Because you don't have spring-boot-starter-web dependency in your pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>    
Alex R
  • 11,364
  • 15
  • 100
  • 180
Sanjay Rawat
  • 2,304
  • 15
  • 30
4

As already noted in other answers the simplest solution is to add a property:

  • spring.main.web-application-type=NONE for Spring-boot 2.x
  • spring.main.web-environment=false for Spring-boot 1.x

But the simplest solution is NOT the best one, it's just quick&dirty. Spring-boot has a lot of autoconfigurations that are triggered by the content of your classpath, so you probably have some unnecessary web-related dependency in your app.

I had a Spring-batch application that was giving

Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.

It was caused by the presence of javax.servlet-api in my POM. I removed it and the problem disappeared.

Pino
  • 7,468
  • 6
  • 50
  • 69
-1
public static void main(String[] args) {
    SpringApplication(Application.class)
       .setWebApplicationType(WebApplicationType.NONE)
       .run(args);
}

is another way instead of using the SpringApplicationBuilder.

Abhijit Sarkar
  • 21,927
  • 20
  • 110
  • 219