ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean
Trying to set up a simple web application scheduler. So, here is my config:
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework</groupId>
<artifactId>scheduler</artifactId>
<version>0.1.0</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>1.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>1.1.7.RELEASE</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<properties>
<start-class>hello.Application</start-class>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>hello.Application</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>http://repo.spring.io/libs-release</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>http://repo.spring.io/libs-release</url>
</pluginRepository>
</pluginRepositories>
</project>
My classes look like below
@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application implements WebApplicationInitializer {
public static void main(String[] args) throws Exception {
SpringApplication.run(ScheduledTasks.class);
}
public void onStartup(ServletContext arg0) throws ServletException {
SpringApplication.run(ScheduledTasks.class);
}
@Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
factory.setPort(8081);
factory.setSessionTimeout(50, TimeUnit.MINUTES);
return factory;
}
}
@EnableScheduling
public class ScheduledTasks {
@Scheduled(fixedRate = 500)
public void reportCurrentTime() {
System.out.println("Testing successful ");
}
}
But when I try to start the container I see the exception
ERROR 2592 --- [ost-startStop-1] o.s.boot.SpringApplication : Application startup failed
...
...
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:174)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:147)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:121)
... 20 more
I tried to do Spring Boot Testing: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean , but in vain.
Please suggest, thanks
source to share
You only use ScheduledTasks
:
SpringApplication.run(ScheduledTasks.class);
when should you run:
SpringApplication.run(Application.class);
Running ScheduledTasks means Spring Boot is not aware of the configuration in Application
. Realistically, this means it doesn't see @EnableAutoConfiguration
, which is what enables auto-configuration, and since you have Tomcat in the classpath, a built-in Tomcat instance is created.
I would fix this by moving the annotation @EnableScheduling
from ScheduledTasks
to Application
, working Application.class
instead of ScheduledTasks.class
, and annotating ScheduledTasks
with @Component
:
Application.class:
@Configuration
@EnableAutoConfiguration
@ComponentScan
@EnableScheduling
public class Application implements WebApplicationInitializer {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class);
}
// …
}
ScheduledTasks.class
@Component
public class ScheduledTasks {
@Scheduled(fixedRate = 500)
public void reportCurrentTime() {
System.out.println("Testing successful ");
}
}
Moving @EnableScheduling
means it belongs to the config class where it belongs. Launching Application.class
means that Spring Boot sees all of its configuration, including enabling bean scanning and auto-configuration. Annotated ScheduledTasks
with @Component
means that it was detected by component scan and its method was found @Scheduled
.
It should work and work. I would also fix your pom so that you don't use a mixture of Spring Boot versions (you have 1.1.6 and 1.1.7 for now) and get rid of the EmbeddedServletContainerFactory
bean to the advantage of setting the port and session timeout with application.properties
in src/main/resources
instead of:
application.properties:
server.port = 8081
server.session-timeout = 3000
source to share
other than what @Andy Wilkinson pointed out, which is true in the OP's case, but not in mine
I saw that my spring-boot-starter-tomcat was with
<scope>provided</scope>
(since I was adding a servlet initializer to run it on wildfly) I commented out this bit and removed it from the spring-boot-starter-tomcat dependency and it started working. Adding here just in case anyone else has the same problem
source to share