Referencing the Application in a constructor

Hi,

I’ve been toying with the idea of getting rid of load-time-weaving in our Spring & Vaadin project. I’m hoping to perform autowiring in constructors with a method call to:

    public static void autowire(Application application, Object target) {
        ServletContext servletContext = ((WebApplicationContext)application.getContext()).getHttpSession().getServletContext();
        ApplicationContext applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext); // Spring app context
        
        AutowiredAnnotationBeanPostProcessor annotationBeanPostProcessor = new AutowiredAnnotationBeanPostProcessor();
        annotationBeanPostProcessor.setBeanFactory(applicationContext.getAutowireCapableBeanFactory());
        annotationBeanPostProcessor.processInjection(target);
    }

The method runs fine, but I have a problem with the Application parameter.
getApplication()
- method doesn’t give a reference to the application, the Component is apparently not “connected” until a later stage.

Passing Application around as a reference to constructors would be far from ideal. For example if a have a chain Components being initialized, but only the last one needs Autowiring, I would need to pass the application down the chain.

And I wouldn’t want to autowire after the constructor, that would limit my options when running the constructor.

So is there an elegant solution to this? Can I access the application - or actually the WebApplicationContext - easily from a constructor?

Hi,

The most commonly used solution to avoid passing around the application reference (for constructors needing that) is “the ThreadLocal Pattern”. This might be the solution for you too.

See article about this in wiki:
http://vaadin.com/wiki/-/wiki/Main/ThreadLocal%20Pattern

Could you think of using compile time weaving instead? Example found
here
.

Hi Petri,

I would love to use compile time weaving, but I’m having difficulties in getting it to work. I have an existing project that uses load-time-weaving and annotations which doesn’t work with the spring-configured annotation. My xml should be ok. Here’s the xml for configuration and a single bean I want to autowire.

  <context:spring-configured/>
  <context:component-scan base-package="package.name.here" />
  
  <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
  <bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />

   <bean id="sessionObject" class="package.name.here.SessionObject" scope="session">
    <aop:scoped-proxy />
   </bean>

In Java I autowire it:

@Configurable(preConstruction=true)
public class MyClass {
@Autowered
private SessionObject sessionObject;
}

And when I try to reference the object, I get a null when using spring-configured. Changing the line
context:spring-configured/
into
context:load-time-weaver/
results in working code.

There’s probably some conflicting configuration somewhere. I’ll try working from an empty project and see if I find it.

Spring configuration is so easy to mess up. Fortunately there is now Spring Roo. You should really try that since it makes these configurations automatically. Also Spring STS is good choice if you are using Spring technologies.

I checked your example and I’m quite curious about it. You do quite a bit of work around AbstractApplicationServlet in order to get the Application running.

With load-time-weaving I can simply have a plain Vaadin application class with no annotations, and whenever a Component needs access to a Spring bean, it can state:

@Configurable (preConstruction=true)
public class ClubTable extends LazyLoadingTable<Club> {

    @Autowired
    private ClubService clubService;
}

and autowiring does the magic.

Is it possible to use compile time weaving without having to resort to tricks with the AbstractApplicationServlet?

I’ll do some more testing after I get some sleep…

I wrote SpringApplicationServlet mainly because of the fact that demo app uses Spring i18n. And of course then you can get application from Spring container. Compile time weaving has nothing to do with it so you can use core Vaadin application servlet.

Sorry for being so thick-headed, but it looks like there’s some part of configuration I’m just not getting. Here’s a very concrete question:

Using your project from incubator as a base, I make the following class:

@Configurable(preConstruction=true)
public class TestApplication extends Application {

	private static final long serialVersionUID = 1L;

	@Autowired
	private FooService fooService;
	
	@Override
	public void init() {
        Window main = new Window("Hello window"); 
        setMainWindow(main);
        main.addComponent(new Label("Hello World!"));
        System.err.println("Value of injected service: "+fooService);
	}
}

and map a request to the TestApplication in web.xml:

	<servlet>
		<servlet-name>Direct Test Application</servlet-name>
  		<servlet-class> com.vaadin.terminal.gwt.server.ApplicationServlet</servlet-class>
	  	<init-param>
  			<param-name>application</param-name>
  			<param-value>com.vaadin.incubator.spring.ui.TestApplication</param-value>
  		</init-param>
	</servlet>

When I enter the application in a browser window, the fooService does not get injected. You can try this yourself. There’s probably a simple explanation, which I would love to hear.

Furthermore, the above class and xml would work with a load-time-weaver, so there’s definitely some difference in configuration needed between load-time and compile-time.

I finally found the problem with kind help from Henri Sara.

The applications themselves are in good order, the server just needs different libraries for load time and compile time weaving.

Now if I can just find the correct set I can get my old tomcat up and running… or I could just switch our project to Maven, this is a pretty good reason for it anyway.

Thanks for the example project, Petri.

Thanks Valtteri. I made example project because Vaadin core doesn’t have any support for Spring and knowing many people is using it. I’m using Spring because of better support for AspectJ. Ok JEE6 is close but I haven’t seen so many application servers supporting it yet (specially Spring Configurable annotation kick ass). And there is example of using Bean Validation that I love to see in Vaadin. There is even a ticket for it but I haven’t seen any progression. Maybe there is more important thinks that Vaadin people is tackling for like this Drag and Drop support that I don’t really need.

But what comes to your project I was thinking that you are using maven. Maven is really good if you don’t try it to make too difficult. For example forget these multi module things that maven have. Just use war project and then have dependencies to maven java projects of your own if you have any. Multi module is just major pain and you certainly will have problems (at least if you are using release plugin and Eclipse flat project structure). But what comes to compile time weaving this makes the trick in maven (hint Spring Roo makes these configurations for you):

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>aspectj-maven-plugin</artifactId>
    <version>1.0</version>
    <dependencies>
         <dependency>
             <groupId>org.aspectj</group>
             <artifactId>com.springsource.org.aspectj.runtime</artifactId>
             <version>${aspectj.version}</version>
         <dependency>
         <dependency>
             <groupId>org.aspectj</groupId>
             <artifactId>com.springsource.org.aspectj.tools</artifactId>
             <version>${aspectj.version}</version>
         </dependency>
    </dependencies>
    <executions>
        <execution>
            <goals>
                <goal>compile</goal>
                <goal>test-compile</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <aspectLibraries>
            <aspectLibrary>
                <groupId>org.springframework</groupId>
                <artifactId>org.springframework.aspects</artifactId>
             </aspectLibrary>
        </aspectLibraries>
        <source>1.6</source>
        <target>1.6</target>
        <encoding>ISO-8859-1</encoding>
    </configuration>
</plugin>

PS.

And I hope that maven3 makes this verbose xml disappearing (using of attributes). Maven is not Ant. Don’t try same things you make with Ant (even there is antrun plugin). Just simplify your build process. I have seen so many people complaining about maven because of that. If you don’t like maven don’t use it. Use for example Ivy.

Hi,
long time from the last post, but I am interesting about pros and cons of load-time versus compile-time weaving.
what do you think is better in case of using it in Vaadin?