I have referred to a very helpful previous post but facing a different issue while injecting a bean in a ServletContextListener
The Listener
package sapphire.social.connector.listener; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.web.context.support.WebApplicationContextUtils; import sapphire.adapter.youtube.YTConnectorMgr; import sapphire.social.connector.logger.LogManager; public class AppServletContextListener implements ServletContextListener { @Override public void contextDestroyed(ServletContextEvent arg0) { // TODO Auto-generated method stub if (LogManager.isDebugOn()) { LogManager .debug("AppServletContextListener ::: contextDestroyed :::"); } } @Override public void contextInitialized(ServletContextEvent initializingEvent) { // TODO Auto-generated method stub if (LogManager.isDebugOn()) { LogManager .debug("AppServletContextListener ::: contextInitialized :::"); } if (LogManager.isDebugOn()) { LogManager .debug("AppServletContextListener ::: contextInitialized ::: WebApplicationApplicationContext : " + WebApplicationContextUtils .getWebApplicationContext(initializingEvent .getServletContext())); } if (LogManager.isDebugOn()) { LogManager .debug("AppServletContextListener ::: contextInitialized ::: RequiredWebApplicationApplicationContext : " + WebApplicationContextUtils .getRequiredWebApplicationContext(initializingEvent .getServletContext())); } YTConnectorMgr ytConnectorMgr = (YTConnectorMgr) WebApplicationContextUtils .getWebApplicationContext(initializingEvent.getServletContext()) .getAutowireCapableBeanFactory() .autowire(YTConnectorMgr.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true); if (LogManager.isDebugOn()) { LogManager .debug("AppServletContextListener ::: contextInitialized ::: ytConnectorMgr : " + ytConnectorMgr); } } } The web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <!-- <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/sapphire-security.xml</param-value> </context-param> --> <listener> <listener-class>sapphire.social.connector.listener.AppServletContextListener</listener-class> </listener> <servlet> <servlet-name>central-config</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>central-config</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app> central-config-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd"> <context:component-scan base-package="sapphire" /> <mvc:annotation-driven /> <!-- Start : To by-pass MVC view resolution and pass the response to appropriate media type view resolvers/views Deprecated approach since Spring 3.2.x --> <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> <property name="favorPathExtension" value="false"></property> <property name="mediaTypes"> <map> <entry key="json" value="application/json" /> <entry key="xml" value="text/xml" /> <entry key="htm" value="text/html" /> </map> </property> <property name="viewResolvers"> <list> <bean class="org.springframework.web.servlet.view.BeanNameViewResolver" /> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/" /> <property name="suffix" value=".jsp" /> </bean> </list> </property> <!-- <property name="defaultContentType" value="application/json" /> <property name="defaultViews"> <list> <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" /> </list> </property> --> </bean> <!-- End : To by-pass MVC view resolution and pass the response to appropriate media type view resolvers/views Deprecated approach since Spring 3.2.x --> <task:scheduler id="scheduler" pool-size="5" /> <task:annotation-driven scheduler="scheduler" /> </beans> I attempted to retrieve both WebApplicationContext and Required WebApplicationContext - the former came null and the latter requires a ContextLoaderListener
Fri Nov 15 12:05:55 IST 2013 [Thread-2] AppServletContextListener ::: contextInitialized ::: Nov 15, 2013 12:05:55 PM org.apache.catalina.core.StandardContext listenerStart SEVERE: Exception sending context initialized event to listener instance of class sapphire.social.connector.listener.AppServletContextListener java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered? at org.springframework.web.context.support.WebApplicationContextUtils.getRequiredWebApplicationContext(WebApplicationContextUtils.java:84) at sapphire.social.connector.listener.AppServletContextListener.contextInitialized(AppServletContextListener.java:44) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4723) at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5226) at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5221) at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source) at java.util.concurrent.FutureTask.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source) Nov 15, 2013 12:05:55 PM org.apache.catalina.core.StandardContext startInternal SEVERE: Error listenerStart Nov 15, 2013 12:05:55 PM org.apache.catalina.core.StandardContext startInternal SEVERE: Context [/Sapphire] startup failed due to previous errors Fri Nov 15 12:05:55 IST 2013 [Thread-2] AppServletContextListener ::: contextInitialized ::: WebApplicationApplicationContext : null Fri Nov 15 12:05:55 IST 2013 [stop children - Catalina:j2eeType=WebModule,name=//tenantarchtst.lntinfotech.com/Sapphire,J2EEApplication=none,J2EEServer=none] AppServletContextListener ::: contextDestroyed ::: Nov 15, 2013 12:05:55 PM org.apache.coyote.AbstractProtocol start INFO: Starting ProtocolHandler ["http-bio-8081"] Nov 15, 2013 12:05:55 PM org.apache.coyote.AbstractProtocol start INFO: Starting ProtocolHandler ["ajp-bio-8010"] Nov 15, 2013 12:05:55 PM org.apache.catalina.startup.Catalina start INFO: Server startup in 15184 ms Just for reference, giving the bean that I want to inject in the ServletContextListener :
@Component(value = "YTConnectorMgr") public class YTConnectorMgr extends ConnectorMgr { private static int maxWorkerThreads = 5; public YTConnectorMgr(int maxWorkerThreads, ConnectorType connectorType) { super(maxWorkerThreads, connectorType); } } I'm having a single config xml file which is taken care by the DispatcherServlet - ideally, I don't require a ContextLoaderListener! But even this previous post dictates the use of a ContextLoaderListener. As pointed by M.Deinum, I should NOT be duplicating my beans !!!
ContextLoaderListenerandDispatcherServletconstruct and application context containing everything from central-config-servlet.xml. Instead ofgetWebApplicationContexttrygetRequiredWebApplicationContext. The logic in there makes me wonder why aren't you simply registering this bean in theApplicationContextand use@Scheduled?ServletContextListenerannotate those with@Autowiredand instead of doing lookups simply callconfigureBeanwith your current instance of theServletContextListener. Saves you all the uglygetInstancemethods and you are basically leveraging spring.ContextLoaderListeneris configured before yourAppServletContextListener. The latter contains@Autowiredannotated fields. Now in yourcontextInitializedsimply callautowire(this)(instead of theYTConnectorMgr). This will inject the dependencies into your listener. But I still wonder why do you need this listener? What is so special about it that you cannot use the ApplicationContext to wire everything together?