0

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 !!!

6
  • 1
    You are aware that you are loading the configuration twice, effectively duplicating all of your beans??? (Both the ContextLoaderListener and DispatcherServlet construct and application context containing everything from central-config-servlet.xml. Instead of getWebApplicationContext try getRequiredWebApplicationContext. The logic in there makes me wonder why aren't you simply registering this bean in the ApplicationContext and use @Scheduled? Commented Nov 14, 2013 at 9:47
  • @M.Deinum Actually, I hadn't configured the ContextLoaderListener initially as it made no sense but I guess it is required to retrieve the WebApplicationContext. Have edited my question and posted the exception too - can u have a look? Commented Nov 15, 2013 at 6:43
  • 1
    If you want a ServletListener to access an ApplicationContext it will only be able to access the root context. And the ContextLoaderListener needs to be loaded/registered before your own listener (else the context isn't created yet). But why are you making things so complex? Simply use dependency injection. Add fields to your ServletContextListener annotate those with @Autowired and instead of doing lookups simply call configureBean with your current instance of the ServletContextListener. Saves you all the ugly getInstance methods and you are basically leveraging spring. Commented Nov 15, 2013 at 8:08
  • @M.Deinum Err... I couldn't figure out 'instead of doing lookups simply call configureBean with your current instance of the ServletContextListener'. Yes, I will remove the static stuff etc. from the YTConnector but a plain Autowired inServletContextListener will fail ! Commented Nov 15, 2013 at 11:37
  • No it won't you just have to call the correct methods. Make sure that your ContextLoaderListener is configured before your AppServletContextListener. The latter contains @Autowired annotated fields. Now in your contextInitialized simply call autowire(this) (instead of the YTConnectorMgr). 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? Commented Nov 15, 2013 at 17:26

1 Answer 1

0

you may need use @Autowired to injecting beans : try

@Autowired private ScheduledThreadPoolExecutor executor; @Autowired private ScheduledFuture scheduledFuture; 
Sign up to request clarification or add additional context in comments.

2 Comments

I didn't get u - I'm getting NPE for the bean factory and that is where I'm stuck! How does auto-wiring the above instances help ???
I'm so sorry,I didn't see your question clearly before.I tried later,foud that was strange,I wrote a small demo from your code above,it worked!here is the demo (dropbox.com/s/2pslys0wrflp8w2/webtest.rar) ---,you can try it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.