28

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?

4

4 Answers 4

63

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

2
  • Thanks for pointing to a Spring Boot 2 solution; I was looking for a migration from Spring 1.
    – рüффп
    Commented Jan 28, 2019 at 7: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. Commented Dec 3, 2022 at 5: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>    
3
  • Thanks @Sanjay Rawat but if only could disable web environment by setWebEnviroment(false), cannot through excluding some key class to achieve this
    – zhuguowei
    Commented May 16, 2016 at 13:12
  • @zhuguowei See Method #3. Commented May 16, 2016 at 17:43
  • 2
    This answer is obsolete. Please note the other answer for Spring Boot 2.0
    – Alex R
    Commented Sep 26, 2019 at 6:33
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.

-1
public static void main(String[] args) {
    SpringApplication(Application.class)
       .setWebApplicationType(WebApplicationType.NONE)
       .run(args);
}

is another way instead of using the SpringApplicationBuilder.

Not the answer you're looking for? Browse other questions tagged or ask your own question.