Spring: Problem autowiring in other class then Application class

Hello !

I am currently developping an application using Spring MVC, Hibernate and Vaadin.

When I inject a Service in my Application class (with @autowired) everything works fine. The problem is that I cant use this Spring annotation in other classes.

Here is my application class. In this case, I am able to inject my Service and eveything works fine.


public class SubgesteApplication extends Application {

	@Autowired
	private HospitalService service;


	@Override
	public void init() {
....
          ArrayList<Hospital> hospitals = (ArrayList<Hospital>) service.listHospitals();
          Iterator it = hospitals.iterator();
          while (it.hasNext()) {
        	Hospital hospital = (Hospital)it.next();
        	String labelToShow = "id : " + hospital.getId() + " name : " + hospital.getName() + " adresse : " + hospital.getCity();
        	System.out.println(labelToShow);
        }
}

Now, in my Application class, I am creating a SplitPanel. I would like to inject this service in this new class, instead of the Application class.

public class HospitalSplitPanel extends SplitPanel implements Button.ClickListener, Property.ValueChangeListener, ItemClickListener {

	
	@Autowired
	private HospitalService service;
	
	public HospitalSplitPanel() {
		super(SplitPanel.ORIENTATION_HORIZONTAL);		
                ArrayList<Hospital> hospitals = (ArrayList<Hospital>) service.listHospitals();
        }
}

Unfortunately this time I get a NullPointerException. When I debug my programm, I can see that my service is null.

Here is my web.xml

<?xml version="1.0" encoding="ISO-8859-1"?>

<!-- $Id$ -->
<web-app 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"
  version="2.5">

    <display-name>My app</display-name>
    <description>My app</description>

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

    <!-- Spring web request listener: makes the current web request available in a private ThreadLocal -->
    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>

    <!-- Vaadin servlet -->
    <servlet>
        <servlet-name>subgeste</servlet-name>
        <servlet-class>net.sebpx.txvdn.vaadin.util.WebContextApplicationServlet</servlet-class>
        <init-param>
            <param-name>application</param-name>
            <param-value>net.sebpx.txvdn.vaadin.SubgesteApplication</param-value>
        </init-param>
        <init-param>
            <param-name>productionMode</param-name>
            <param-value>false</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>subgeste</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>

And my applicationContext.xml

<?xml version="1.0" encoding="ISO-8859-1"?>

<!-- $Id$ -->
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jee="http://www.springframework.org/schema/jee"
    xmlns:lang="http://www.springframework.org/schema/lang"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
        http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

    <!-- Activate Spring annotation support -->
    <context:annotation-config/>
    <context:component-scan base-package="net.sebpx.txvdn" />

    <!-- Example bean -->
   <!--  <bean class="net.sebpx.txvdn.vaadin.MyBean" p:name="foobar"/>
     <bean class="net.sebpx.txvdn.controller.ContactController"/> -->
    

    <!-- Vaadin application -->
    <bean scope="session" class="net.sebpx.txvdn.vaadin.SubgesteApplication"/>
    <bean scope="session" class="net.sebpx.txvdn.vaadin.hospital.HospitalSplitPanel"/>
    
    
      <bean id="messageSource"
        class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basename" value="/WEB-INF/messages" />
        <property name="defaultEncoding" value="UTF-8" />
    </bean>
    <bean id="propertyConfigurer"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
        p:location="/WEB-INF/jdbc.properties" />

    <bean id="dataSource"
        class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
        p:driverClassName="${jdbc.driverClassName}"
        p:url="${jdbc.databaseurl}" p:username="${jdbc.username}"
        p:password="${jdbc.password}" />

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation">
            <value>/WEB-INF/hibernate.cfg.xml</value>
        </property>
        <property name="configurationClass">
            <value>org.hibernate.cfg.AnnotationConfiguration</value>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${jdbc.dialect}</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
    </bean>
    
    <tx:annotation-driven />
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

</beans>

Does someone know how I could resolve this ?

Thank you !

Sebastian

I have tryed it with the SpringContextHelper described here : https://vaadin.com/wiki/-/wiki/Main/Spring%20Integration
It is working, but I still haven’t found a solution to use annotations.

Hey,

how are you using HospitalSplitPanel in your application? Is it loaded via Spring or are you just instantiating it via a constructor?
If your using the second option you will need a little bit of extra code and know how.

Thank you for your answer !
Yes actually right now I am not loading it via Spring. What am I missing ?

Im just doing something like this in my application:


		TabSheet tabsheet = new TabSheet();
		tabsheet.addTab(new HospitalSplitPanel(this), "Hospitals");

You should inject HospitalSplitPanel and not construct it yourself. Spring should instantiate it for DI to work

Hey,

You basically have 3 options:

1.) Get the HospitalSplitPanel-Bean via the applicationcontext. In this Case you should use the applicationcontextaware Interface to Get the application context and than you can somply call getBean. I would recomend that in this Case you scope the Bean as prototype.

2.) you just “autowire” it via the Bean Factory( you will also need an applicationcontext for this)

3.) you can use @Configurable and AspectJ

Sorry for the Short answer if you want i can Post examples for the three possibilities but right bis i am Writing this Post via my iPhone. And i hate spellchecking…

Ciao,

Christoph

Hi Chris,
In my case , I am seeing that my bean is getting injected into the Vaadin Application class when application is getting deployed. I can see in the
logs that my bean is not null.
But when I am accessing my application as a user in browser, the bean is seen as null in logs. Please advice.
I am not using AspectJ while compile time.

Below is my code. I am trying to inject memberRecipientDao bean in MemberProfile class. The line “mpd is not null” is getting printed first time during deployment.
But for subsequest requests to the Vaadin portlet it is null.

package com.magellanhealth.memberinfo;

public class MemberProfile extends Application {

/**
 * 
 */
private static final long serialVersionUID = 1L;




private MemberRecipientDao memberRecipientDao;

public MemberRecipientDao getMemberRecipientDao() {
	return memberRecipientDao ;
}
public void setMemberRecipientDao(MemberRecipientDao memberRecipientDao) {
	System.out.println("calling setter method for de inj");
	this.memberRecipientDao = memberRecipientDao;
}

@PostConstruct
public void init() {
    Window window = new Window("Vaadin Portlet Application");
    setMainWindow(window);
    System.out.println("inside init method");
    if(this.getMemberRecipientDao() != null){
    	System.out.println("mpd is not null");
    }
    

    H2(window);
 
    
}

}
public void H2(Window window){
	MemberTabbedInfo memberTabbedInfo = new   MemberTabbedInfo();
 	window.addComponent(memberTabbedInfo);
 	System.out.println("hi");
}

}

web.xml snippet

org.springframework.web.context.ContextLoaderListener org.springframework.web.context.request.RequestContextListener

spring context xml

<bean id="memberRecipientDao"
  class="com.magellanhealth.enterprise.member.persistence.orm.impl.MemberRecipientDaoJpa" />
  
<bean id="memberProfile" class="com.magellanhealth.memberinfo.MemberProfile">
    	 <property name="memberRecipientDao"><ref  bean="memberRecipientDao" /></property>
</bean>

Hi avinash,

I’m very, very sorry for the late answer. We’re you able to solve your’re problem. Or could I maybe still helb you?

Ciao,

Christoph

Hi,
I’ve a similar problem. I’m using the following addon to get the spring integration, but autowiring is working only in the first class.
What I’m doing is to switch between tabs using the DiscoveryNavigator with navigator.navigateTo(“/trips”) for example.
This works, but I guess in this way it is still not instantiated by the spring context.
Is there any way to use the navigator with spring?

Hi Christoph,

Sorry for reviving this thread but can you post the solution to his problem using the @Autowire annotation. It seems that we have the same problem. But in my case I’m trying to retrieve some fields and bind them into a table.

Thanks,
Jet.

Hi,
I had the similar problem and the solution of Danny Roest worked. The HospitalSplitPanel must be annoted @Component and be injected in the class that use it. No need to declare HospitalSplitPanel as a bean in the configuration

Hi
I have a problem. I am getting service object as null in vaadin view. Can anyone help me to resolve issue.