Question

I have this class that creates a socket on the java side. The problem is that it's throwing a java.lang.IllegalArgumentException: No bean found for class com.production.workflow.process.approval.ApprovalSocketHandler

package com.production;

@WebListener
public class SocketInitializer implements ServletContextListener {

    public static App app;

    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        AutowireCapableBeanFactory beanFactory = ApplicationContextProvider.getApplicationContext().getAutowireCapableBeanFactory();
        app =  new App(new Options().url("/socket/workstation/approval").packageOf(this), new AtmosphereModule(servletContextEvent.getServletContext()), new SpringModule(beanFactory));
        app.bean(ApprovalSocketHandler.class).init();
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {

    }
}

The package that this class is in, is indeed being scanned via my config. I suspect that at the point this Listener is being initialized that config hasn't yet scanned.

@Configuration
@ComponentScan(basePackages = {
        "com.production"
})
@PropertySource(value= {
        "classpath:/application.properties",
        "classpath:/environment-${MY_ENVIRONMENT}.properties"
})
@EnableJpaRepositories("com.production.repository")
@EnableTransactionManagement
public class Config {
    @Value("${db.url}")
    String PROPERTY_DATABASE_URL;
    @Value("${db.user}")
    String PROPERTY_DATABASE_USER;
    @Value("${db.password}")
    String PROPERTY_DATABASE_PASSWORD;

    @Value("${persistenceUnit.default}")
    String PROPERTY_DEFAULT_PERSISTENCE_UNIT;

    @Value("${hibernate.dialect}")
    String PROPERTY_HIBERNATE_DIALECT;
    @Value("${hibernate.format_sql}")
    String PROPERTY_HIBERNATE_FORMAT_SQL;
    @Value("${hibernate.show_sql}")
    String PROPERTY_HIBERNATE_SHOW_SQL;
    @Value("${entitymanager.packages.to.scan}")
    String PROPERTY_ENTITYMANAGER_PACKAGES_TO_SCAN;

    @Bean
    public App app() {
        return SocketInitializer.app;
    }

What do I need to do in order to ensure this class is a bean during ServletContextListener execution?

Was it helpful?

Solution

The interface ServletContextAware is what you are looking for. It provides the method

setServletContext(ServletContext servletContext) 

which Spring will use to inject the application context. In your case, this will be the ServletContext created by your servlet container.

You should not be using this with ServletContextListener as you have it in your question since a ServletContextListener is initialized by the servlet container and not by Spring. Spring cannot therefore do its magic.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top