Vaadin + Spring + pattern MVP - @Configurable problem

Hello all,

I’m writing a Vaadin application and I’m using Spring 3.2.3 and Vaadin 7.0.7.

I would like to injection Spring beans into non-Spring objects (models of MVP pattern), but @Configurable doesn’t work.

My example:

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"
       xsi:schemaLocation ="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"  id= "WebApp_ID" version = "2.5">
       <display-name > Vaadin Widget Test Application </display-name >

       <!-- Spring -->
       <listener >
             < listener-class> org.springframework.web.context.ContextLoaderListener </listener-class >
       </listener >
       <listener >
             < listener-class> org.springframework.web.context.request.RequestContextListener </ listener-class>
       </listener >
       <context-param >
              < param-name> contextConfigLocation </param-name >
              < param-value> /WEB-INF/applicationContext.xml </param-value >
       </context-param >

       <!-- Vaadin servlet -->
       <servlet >
              < servlet-name> Vaadin </servlet-name >
             < servlet-class> ru.xpoft.vaadin.SpringVaadinServlet </servlet-class >
              < init-param>
                    < param-name> beanName</ param-name >
                    < param-value> mainUI</ param-value >
              </ init-param>
       </servlet >
       <servlet-mapping >
              < servlet-name> Vaadin </servlet-name >
              < url-pattern> /*</ url-pattern >
       </servlet-mapping >

       <context-param >
              < description> Vaadin production mode </ description>
              < param-name> productionMode </param-name >
              < param-value> false</ param-value >
       </context-param >

       <!-- Static mapping -->
       <servlet-mapping >
              < servlet-name> default</ servlet-name >
              < url-pattern> /static/* </url-pattern >
       </servlet-mapping >
</ web-app>

applicationContext:

<? 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:tx= "http://www.springframework.org/schema/tx"
       xmlns:aop ="http://www.springframework.org/schema/aop"
       xmlns:util ="http://www.springframework.org/schema/util"
       xmlns:p= "http://www.springframework.org/schema/p"
       xmlns:context ="http://www.springframework.org/schema/context"
       xmlns:jee ="http://www.springframework.org/schema/jee"
       xsi:schemaLocation ="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
       http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
       http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd" >

       <context:annotation-config />
       <context:spring-configured />
       <context:component-scan base-package= "com.mydomain" />

       <!-- sessionFactory, transactionAppExcAspect, transactionManager etc. -->

</ beans>

MainUI.java

@Component
@Scope ("session" )
public class MainUI extends UI {

        @Autowired
        private AuthenticateService authenticateService; // this autowiring is OK

        private CssLayout rootLayout = new CssLayout ();

        @Override
        protected void init(VaadinRequest request) {
               
                boolean result = authenticateService.authenticate("user" , "password" ); // this call is OK

                SampleModel model = new SampleModel();
                SampleViewImpl view  = new SampleViewImpl();
                 new SamplePresenter(model, view);
               
                model.doAuthenticate(); // this call is WRONG
                  
                 rootLayout .addComponent(view);
                setContent(rootLayout );
       }
}

SampleModel.java

@Configurable
@Scope ("session" )
public class SampleModel {
       
        @Autowired
        private AuthenticateService authenticateService; // this autowiring is WRONG

        public boolean doAuthenticate() {
                return authenticateService.authenticate("user" , "password" ); // this autowiring is WRONG - java.lang.NullPointerException
       }
}

Any tips?

For Spring to autowire beans to non spring-managed classes, you need to use
AOP/weaving.
More specifically, you’ll either need to do compile-time weaving - running the AspectJ compiler - or
load-time weaving
(Depending on your Servlet container, either using an Instrumenting Classloader, or specifying an agent at runtime).

For our project - at development time, we use LTW but as part of our ant build, we compile the Aspects in.

HTH,
Cheers,

Charles

Thanks, AOP/weaving works.

Hi Lukas,

is it possible to post your working code here? Or send it to me as PN?

Cheers
Oliver