Integration of Spring

I know this question have been asked before, but I’ve been trying to get Spring working in Vaadin for three days now and I need answers.


Here’s what I’m doing

I’m using Vaadin, Maven, and Spring in Eclipse. I’m using Tomcat as my server; I’ve tried both mvn tomcat:run and Eclipse Run As Server → Tomcat. Different errors but no luck.

I’ve followed the Wiki solution pretty closely: I have web.xml sections like this:

    <context-param>
        <description>Spring context file</description>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring-context.xml</param-value>
    </context-param>
	
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

I’ve changed the contextConfigLocation param-value to all sorts of things, including classpath*:spring-context, classpath*:/WEB-INF/spring-context.xml and others. One of the things the Wiki never tells you is
where to put the spring-context.xml file.

I have a SpringHelper class with a method like this:

    public SpringContextHelper(Application application) {
        ServletContext servletContext = ((WebApplicationContext) application.getContext()).getHttpSession().getServletContext();
        context = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
    }


Here’s what I’m getting

It is
((WebApplicationContext) application.getContext())
that is returning null when I run as
mvn tomcat:run

When I start the project with Eclipse’s
Run on Server
and run it on a Tomcat server started in Eclipse, I get this error:

SEVERE: Error configuring application listener of class org.springframework.web.context.ContextLoaderListener
java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener
	at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1676)
	at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1521)
	at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:415)
        ....

Hello Knute,

I also had problems at first trying to get Spring Hibernate/JPA and Vaadin integrated. I eventually got it working by using Aspect AOP and compile-time weaving. Here’s my configuration.

The file directory locations are as follows:
src/applicationContext.xml
src/META-INF/persistence.xml
src/META-INF/persistenceKH.xml
src/META-INF/spring/context.xml
WEB-INF/aop.xml

I also had to install the AOP jar files along with the usual jars.

  1. web.xml
<filter>
	<filter-name>osiv1</filter-name>
	<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
	<init-param>
	 	<param-name>entityManagerFactoryBeanName</param-name>
		<param-value>entityManagerFactoryKH</param-value>
	</init-param>
</filter>

<filter>
	<filter-name>osiv2</filter-name>
	<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
	<init-param>
	 	<param-name>entityManagerFactoryBeanName</param-name>
		<param-value>entityManagerFactorySC</param-value>
	</init-param>
</filter>

<filter>
	<filter-name>osiv3</filter-name>
	<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
	<init-param>
	 	<param-name>entityManagerFactoryBeanName</param-name>
		<param-value>entityManagerFactoryRCC</param-value>
	</init-param>
</filter>

<filter>
	<filter-name>osiv4</filter-name>
	<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
	<init-param>
	 	<param-name>entityManagerFactoryBeanName</param-name>
		<param-value>entityManagerFactoryCA</param-value>
	</init-param>
</filter>

<filter-mapping>
	<filter-name>osiv1</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
	<filter-name>osiv2</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
	<filter-name>osiv3</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
	<filter-name>osiv4</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>

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

<context-param>
	<description>
	Vaadin production mode</description>
	<param-name>productionMode</param-name>
	<param-value>false</param-value>
</context-param>
<servlet>
	<servlet-name>pica</servlet-name>
	<servlet-class>com.vaadin.terminal.gwt.server.ApplicationServlet</servlet-class>
	<init-param>
		<description>
		Vaadin application class to start</description>
		<param-name>application</param-name>
		<param-value>com.receptrx.mainwindow.PicaApplication</param-value>
	</init-param>
	<init-param>
		<description>
		Application widgetset</description>
		<param-name>widgetset</param-name>
		<param-value>com.ksg.vatac.widgetset.VatacWidgetset</param-value>
	</init-param>
	
</servlet>
<servlet-mapping>
	<servlet-name>pica</servlet-name>
	<url-pattern>/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
	<servlet-name>pica</servlet-name>
	<url-pattern>/VAADIN/*</url-pattern>
</servlet-mapping>

<session-config>
    <session-timeout>30</session-timeout>
</session-config>
  1. applicationContext.xml - I am using multiple EntityManagerFactories and Transaction managers. I have since read of a better way of doing this but have not had time to go back and change it - but it works.
<context:spring-configured />

<context:component-scan base-package="com.receptrx.*" />

<!-- Turn on @Autowired, @PostConstruct etc support -->
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />

<bean id="entityManagerFactoryKH" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
	<property name="persistenceUnitName" value="keyhealthPU" />
</bean>

<bean id="entityManagerFactoryRCC" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
	<property name="persistenceUnitName" value="rccPU" />
</bean>

<bean id="entityManagerFactorySC" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
	<property name="persistenceUnitName" value="stacyPU" />
</bean>

<bean id="entityManagerFactoryCA" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
	<property name="persistenceUnitName" value="cardPU" />
</bean>

<!--
	enable the configuration of transactional behavior based on
	annotations
-->

<bean id="transactionManagerKH" class="org.springframework.orm.jpa.JpaTransactionManager">
	<property name="entityManagerFactory" ref="entityManagerFactoryKH" />
</bean>
<bean id="transactionManagerRCC" class="org.springframework.orm.jpa.JpaTransactionManager">
	<property name="entityManagerFactory" ref="entityManagerFactoryRCC" />
</bean>

<bean id="transactionManagerSC" class="org.springframework.orm.jpa.JpaTransactionManager">
	<property name="entityManagerFactory" ref="entityManagerFactorySC" />
</bean>

<bean id="transactionManagerCA" class="org.springframework.orm.jpa.JpaTransactionManager">
	<property name="entityManagerFactory" ref="entityManagerFactoryCA" />
</bean>

<tx:annotation-driven transaction-manager="transactionManagerKH" mode="aspectj"/>
<tx:annotation-driven transaction-manager="transactionManagerSC" mode="aspectj"/>
<tx:annotation-driven transaction-manager="transactionManagerRCC" mode="aspectj"/>
  1. Spring context.xml

    context:annotation-config/
    context:spring-configured/
    <context:component-scan base-package=“com.kumasi.*”/>

  1. Aspectj config file
<!--
<weaver options="-showWeaveInfo"/>
-->

<aspects>
	<aspect name="org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect"/>
	<aspect name="org.springframework.scheduling.aspectj.AnnotationAsyncExecutionAspect"/>
	<aspect name="org.springframework.transaction.aspectj.AnnotationTransactionAspect"/>
</aspects>

Hope this help.

I have tried many different spring integration solutions for vaadin but all-in-all I ended up using the addon Spring-stuff.
It’s has actually solved more problems than I anticipated. It’s structure is very nice, two applicationContexts. One for application wide definitions and one for application instance definitions. I really recommend it.

Thanks, Darryl.

I’m not as familiar with Aspect AOP as I should be. Two questions: 1) what is the AsepctJ file called and where does it go? and 2) could you give me some sample code for how you would get the Spring context into the class?

One more thing: I’m building a war file, but in development, do you use Eclipse? If so, do you use a Maven tomcat:run goal or start a Tomcat server in Eclipse to run the project?

Bart,

I don’t know about the Spring addon. Where can I get it?

There is a nice implementation of a Vaadin project with Spring here:


sat-tracker

This guy is using an OpenJPA for its persistence

It’s available in the Vaadin Add-ons section.
https://vaadin.com/directory#addon/spring-stuff

Hi Knute ,
We have found interesting way to use Spring 3+ and JPA 2.0 together with the help of dynamic proxies.

You can find it posted
here
. There you can find and download SpringJPA project with all documentation.