Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean

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

like image 778
Raghuveer Avatar asked Mar 18 '23 18:03

Raghuveer


1 Answers

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
like image 138
Andy Wilkinson Avatar answered Mar 20 '23 21:03

Andy Wilkinson