Trying to setup a simple web application scheduler. So here is my configuration:
<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 follow Spring Boot Testing: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean but in vain.
Kindly suggest, thanks
You are only running ScheduledTasks
:
SpringApplication.run(ScheduledTasks.class);
when you should run:
SpringApplication.run(Application.class);
Running ScheduledTasks means that Spring Boot doesn't know about the configuration in Application
. Crucially, it means that it doesn't see @EnableAutoConfiguration
which is what switches on auto-configuration and, because you have Tomcat on the classpath, creates the embedded Tomcat instance.
I would fix this by moving the @EnableScheduling
annotation from ScheduledTasks
to Application
, running Application.class
rather than 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 that its on a configuration class, where it belongs. Running Application.class
means that Spring Boot sees all of its configuration, including enabling component scanning and enabling auto-configuration. Annotating ScheduledTasks
with @Component
means that it's found by component scanning and its @Scheduled
method is detected.
This should get things up and running. I would also correct your pom so that you're not using a mixture of versions of Spring Boot (you have 1.1.6 and 1.1.7 in there at the moment) and get rid of your EmbeddedServletContainerFactory
bean in favour of configuring the port and session timeout using application.properties
in src/main/resources
instead:
application.properties:
server.port = 8081
server.session-timeout = 3000
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With