Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring boot No WebApplicationContext found

I have a simple spring boot app and I'm trying to get it up and running. The config consists of an app context ( applicationContext.xml) XML with a bunch of beans in it. I have a Spring application class:

@SpringBootApplication
@Configuration
@ImportResource("classpath:applicationContext.xml")
public class WebCheckApplication {

    private static final Logger logger = Logger.getLogger(WebCheckApplication.class);

    public static void main(String[] args) {
        ApplicationContext ctx = SpringApplication.run(WebCheckApplication.class, args);

        if (logger.isDebugEnabled()) {
            logger.debug("Let's inspect the beans provided by Spring Boot:");

            String[] beanNames = ctx.getBeanDefinitionNames();
            Arrays.sort(beanNames);
            for (String beanName : beanNames) {
                logger.debug(beanName);
            }
        }
    }
}

And I have a @WebListener class that grabs a few beans from the WebContext from within the ServletContext:

@WebListener
public class SystemPropertiesContextInitializer extends SysPropsAlertsFetcher implements ServletContextListener {

    private static final Logger logger = Logger.getLogger(SystemPropertiesContextInitializer.class);

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        //remove the SystemProperties and alert types map object from context
        sce.getServletContext().removeAttribute(BaseAuthenticatedController.SYSPROPS_KEY);
        sce.getServletContext().removeAttribute(BaseAuthenticatedController.ALERT_TYPES_MAP_KEY);
    }

    @Override
    public void contextInitialized(ServletContextEvent sce) {

        SysPropsDataAccess = (SystemPropertiesDataAccess) WebApplicationContextUtils.getRequiredWebApplicationContext(sce.getServletContext()).getBean("SystemPropertiesDataAccess");
        AlertsDataAccess = (AlertDataAccess) WebApplicationContextUtils.getRequiredWebApplicationContext(sce.getServletContext()).getBean("AlertsDataAccess");
        fetchObjects(sce.getServletContext());
    }
}

When I attempt to start the app, I get the following error:

SEVERE: Exception sending context initialized event to listener instance of class web.SystemPropertiesContextInitializer
java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered?
    at org.springframework.web.context.support.WebApplicationContextUtils.getRequiredWebApplicationContext(WebApplicationContextUtils.java:83)
    at .web.SystemPropertiesContextInitializer.contextInitialized(SystemPropertiesContextInitializer.java:31)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4994)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5492)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)

and it occurs at this line:

SysPropsDataAccess = (SystemPropertiesDataAccess) WebApplicationContextUtils.getRequiredWebApplicationContext(sce.getServletContext()).getBean("SystemPropertiesDataAccess");

It looks like Spring isn't creating a WebApplicationContext.

like image 858
alessandro ferrucci Avatar asked Nov 10 '22 02:11

alessandro ferrucci


1 Answers

Greater than or equal 1.3.0.RC1 use @ServletComponentScan

@ServletComponentScan // <-- This scans for EJB @WebFilter, @WebListener and @WebServlet 
@SpringBootApplication
@ImportResource("classpath:applicationContext.xml")
public class WebCheckApplication {

Less than or equal 1.2.x use @Component to scan for listener

@Component // <-- This allows the component to be found by @ComponentScan inside of @SpringBootApplication
@WebListener
public class MojoSystemPropertiesContextInitializer extends MojoSysPropsAlertsFetcher implements ServletContextListener {

War Deploy extend SpringBootServletInitializer

public class WebCheckApplication extends SpringBootServletInitializer {

In 1.3.0.RC1 @ServletComponentScan was added so simply annotating your main application config should allow these to be picked up. Otherwise adding @Component to your ServletContextListener should work

This link is a discussion on how they currently handle @WebFilter how they decided to handle @WebFilter and they also discuss SpringBootServletInitializer and how this would pick process each item twice if both were to be used. Also links to the commits that implement the new feature.

https://github.com/spring-projects/spring-boot/issues/2290

If you intend to deploy your application as a war file you may also have your main configuration extend SpringBootServletInitializer

http://docs.spring.io/spring-boot/docs/current/reference/html/howto-traditional-deployment.html

like image 170
Zergleb Avatar answered Jan 04 '23 03:01

Zergleb