0

A bean defiend on the applicationContext.xml is getting instantiated using both ClassPathXmlApllicationContext and WebApplicationContext. While using the former the bean is returned as expected but while using the latter, WebApplicationContext, I'm getting a null value.

FYI: Not using the Spring to its full extent. Just used to define a bean and to intialize it. Its a web service application based on jboss.

I defined the WebApplicationContext in my web.xml as below

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
     xmlns="http://java.sun.com/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

     <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
</context-param>

<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>

<servlet>
    <display-name>Service</display-name>
    <servlet-name>MService</servlet-name>
    <servlet-class>
        com.xyz.atop.ws.memb.MServiceImpl
    </servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>MService</servlet-name>
    <url-pattern>/Service</url-pattern>
</servlet-mapping>
</web-app>

The entry from the applicationContext.xml

 <beans ...>
 <context:annotation-config />

 <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>

 <bean id="helper" name="helper" class="com.xyz.svc.wrapper.Helper">
    <constructor-arg type="java.lang.String" value="ABC"/> 
 </bean>
 </beans>

Used the ClassPathApplicationContext (returning a bean instance as expected) in my code as below

private static Helper helper;

public MServiceImpl() {
}    
static {
    ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext.xml");
    helper = (Helper) appContext.getBean("helper");
}
......
......

While using the WebApplicationContext, I tried @Autowired annotation and even tried setter injection. Both the ways I'm getting a null value returned.

The "Helper" class I'm trying to initialize is coming from a jar file which in turn makes calls to a cxf-spring application.

Please look at the above scenario and advise to get rid of the null pointer while using the WebApplicationCOntext.

Bharath ABK
  • 324
  • 3
  • 4
  • 16

2 Answers2

0

Ok, spring beans are injected into other spring beans. MService needs to be a bean too. Autowire will then inject the helper into the MService bean. You can't use a static initializer to do this, because that is run at classload time, which is before the application context has loaded. Also, helper shouldn't be static -- that's bad practice -- it makes testing very difficult.

Software Engineer
  • 15,457
  • 7
  • 74
  • 102
  • That makes sense. But my question now to you would be "why the spring bean instance is returned as null when I'm trying to use WebApplicationContext and Autowiring?" – Bharath ABK May 08 '14 at 19:15
  • It's most probably a problem with the order of loading in your app. Your static initializer is run when the class is loaded by the classloader, which is before your application context has been initialized. To make this work you'd have to register yourself as a listener to the event that is raised when the context has completed initialization. See this question for info: http://stackoverflow.com/questions/8686507/how-to-add-a-hook-to-the-application-context-initialization-event – Software Engineer May 08 '14 at 20:26
  • I'm not using both ClassPathApplicationContext and WebApplicationContext at the same time. If I use ClassPathApplicationCOntext then the entry in the web.xml to load the context file is removed and when I try to use WebApplicationContext then I add the entries in the web.xml and remove the static block from the implementation class and replace it with a @Autowired annotation for the non-static private class "Helper" – Bharath ABK May 08 '14 at 21:05
  • Same problem though. The static initializer runs as soon as your class is loaded, which is probably well before the spring application context has had time to load -- however it's booted. – Software Engineer May 08 '14 at 21:30
0

Scenario: Used WebApplicationContext to intialize the beans defined in the applicationCOntext.xml file and received a null while trying to use the instantaited bean object in the code after autowiring.

Issue in this scenario: I'm trying to autowire a spring bean in a class on which Spring has control over.

Solution: Extending the Servlet class (Class which is not in Spring control) which is the endpoint of my JBOSS WS with Spring's SpringBeanAutowiringSupport class helped me resolve the issue.

Below is the code snippet

public class MServiceImpl extends SpringBeanAutowiringSupport implements MService{

     @Autowired
     private Helper helper;

     public MServiceImpl() {
     }    
......
......
}

Figured out that using static block to initialize the spring bean is bad approach. Thanks to @Engineer Dollery

Bharath ABK
  • 324
  • 3
  • 4
  • 16