Spring integration helper class

You are slightly confused. There is no difference. Please read the Spring documentation to understand how aspects are used with Spring (it’s too complicated for me to explain here).

The
@VaadinConfigurable
aspect works just like Spring’s
@Configurable
. The only difference is the application context which it uses to configure the bean.

Can’t tell for sure because you omitted the top of the stack trace, but this can happen if you are not executing within a Vaadin servlet HTTP request thread (or
ContextApplication.invoke()
).

Otherwise, maybe your Vaadin application is not a subclass of
ContextApplication
.

In all due fairness, I might be confused. I tried a lot of different combinations to see how one differs from the other, and I may be remembering things differently. I will try to put together a sample app example if I can reproduce the discrepancy I mentioned.

After a lot of painful searching, indeed, I found the bug. I had a bean wired in my Spring context that used the same VaadinConfigurable bean and hence when the VC bean was being created, it was trying to inject dependencies from a non-existant context. Fixed the wiring issue and this problem seems to be resolved.

Thanks!

Eric

Hi,
I’ve just converted my whole project (based on Vaadin 6.8.5) to use Spring Stuff. Thanks for this work - it looks very good and having Spring context per Vaadin application/session is great!


Unfortunately I am running into the following problem - when I change any class and it is auto-deployed (I’m starting Tomcat 7.0.32 from my STS IDE) and use auto-publishing of webapps.

[b]

  1. Here you can see how the server initially starts:
    [/b]

14-Nov-2012 15:15:09 org.apache.catalina.core.AprLifecycleListener init
14-Nov-2012 15:15:09 org.apache.tomcat.util.digester.SetPropertiesRule begin
WARNING: [SetPropertiesRule]
{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.jee.server:org.lhasalimited.vitic.presentation.implementation.vaadin' did not find a matching property.
14-Nov-2012 15:15:09 org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-bio-8080"]

14-Nov-2012 15:15:09 org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["ajp-bio-8009"]

14-Nov-2012 15:15:09 org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 319 ms
14-Nov-2012 15:15:09 org.apache.catalina.core.StandardService startInternal
INFO: Starting service Catalina
14-Nov-2012 15:15:09 org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet Engine: Apache Tomcat/7.0.32
14-Nov-2012 15:15:12 org.apache.catalina.core.ApplicationContext log
INFO: No Spring WebApplicationInitializer types detected on classpath
14-Nov-2012 15:15:13 org.apache.catalina.core.ApplicationContext log
INFO: Initializing Spring root WebApplicationContext
14-Nov-2012 15:15:15 org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-8080"]

14-Nov-2012 15:15:15 org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-bio-8009"]

14-Nov-2012 15:15:15 org.apache.catalina.startup.Catalina start
INFO: Server startup in 6160 ms
14-Nov-2012 15:15:21 com.vaadin.terminal.gwt.server.AbstractApplicationServlet checkProductionMode
WARNING: 
=================================================================
Vaadin is running in DEBUG MODE.
Add productionMode=true to web.xml to disable debug features.
To show debug window, add ?debug to your application URL.
=================================================================


2. Here comes first request, which creates first ViticApplication and Spring context:


INFO : org.lhasalimited.vitic.presentation.implementation.vaadin.ViticApplication - ViticApplication constructor invoked
INFO : org.lhasalimited.vitic.presentation.implementation.vaadin.ViticApplication - loading application context for Vaadin application ViticApplication
INFO : org.lhasalimited.vitic.presentation.implementation.vaadin.ViticApplication - ViticApplication.setBeanFactory() invoked
INFO : org.lhasalimited.vitic.presentation.implementation.vaadin.ViticApplication - ViticApplication.afterPropertiesSet() invoked
INFO : org.lhasalimited.vitic.presentation.implementation.vaadin.ViticApplication - initializing ViticApplication application...


3. After a while, I change something in a code, and STS performs auto-deploy -
that’s when the errors occur
:


14-Nov-2012 15:15:48 org.apache.catalina.core.StandardContext reload
INFO: Reloading Context with name 
[/vitic] has started
14-Nov-2012 15:15:48 org.apache.catalina.core.ApplicationContext log
INFO: Closing Spring root WebApplicationContext
14-Nov-2012 15:15:52 org.apache.catalina.core.ApplicationContext log
INFO: No Spring WebApplicationInitializer types detected on classpath
14-Nov-2012 15:15:52 org.apache.catalina.core.ApplicationContext log
INFO: Initializing Spring root WebApplicationContext
INFO : org.lhasalimited.vitic.presentation.implementation.vaadin.ViticApplication - loading application context for Vaadin application ViticApplication
14-Nov-2012 15:15:55 org.apache.catalina.session.StandardManager startInternal
SEVERE: Exception loading sessions from persistent storage
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'viticApplication' defined in ServletContext resource 
[/WEB-INF/ViticApplication.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public static org.dellroad.stuff.vaadin.ContextApplication org.dellroad.stuff.vaadin.ContextApplication.get()]
 threw exception; nested exception is java.lang.IllegalStateException: no current application found
	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:581)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1015)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:911)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:605)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:925)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:472)
	at org.dellroad.stuff.vaadin.SpringContextApplication.loadContext(SpringContextApplication.java:307)
	at org.dellroad.stuff.vaadin.SpringContextApplication.readObject(SpringContextApplication.java:317)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:969)
	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1848)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
	at java.util.HashMap.readObject(HashMap.java:1029)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:969)
	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1848)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
	at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946)
	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
	at org.apache.catalina.session.StandardSession.readObject(StandardSession.java:1595)
	at org.apache.catalina.session.StandardSession.readObjectData(StandardSession.java:1060)
	at org.apache.catalina.session.StandardManager.doLoad(StandardManager.java:284)
	at org.apache.catalina.session.StandardManager.load(StandardManager.java:204)
	at org.apache.catalina.session.StandardManager.startInternal(StandardManager.java:491)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5294)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	at org.apache.catalina.core.StandardContext.reload(StandardContext.java:3920)
	at org.apache.catalina.loader.WebappLoader.backgroundProcess(WebappLoader.java:426)
	at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1345)
	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1530)
	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1540)
	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1540)
	at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1519)
	at java.lang.Thread.run(Thread.java:662)
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public static org.dellroad.stuff.vaadin.ContextApplication org.dellroad.stuff.vaadin.ContextApplication.get()]
 threw exception; nested exception is java.lang.IllegalStateException: no current application found
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:181)
	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:570)
	... 52 more
Caused by: java.lang.IllegalStateException: no current application found
	at org.dellroad.stuff.vaadin.ContextApplication.get(ContextApplication.java:334)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:160)
	... 53 more
14-Nov-2012 15:15:55 org.apache.catalina.core.StandardContext reload
INFO: Reloading Context with name 
[/vitic] is completed

Can you please advise me what to do? If you need anymore data from me, please don’t hesitate to ask.
Piotr

Hi again,
just to assure you:

the following definition:


<bean id="viticApplication" class="org.dellroad.stuff.vaadin.ContextApplication" factory-method="get" />

is in my ViticApplication.xml file.

Cheers,
Piotr

That is not a critical error. To my knowledge, it is related to the way that Vaadin serializes session information and stores it in the Tomcat session. When you restart Tomcat (or when STS does an auto-redeploy), Tomcat tries to reload the existing session information into memory so you can continue from the point you were at. However, if you have changed something in the code that is being serialized, Tomcat will not be able to unserialize the session data and will throw the error to inform you.

It is not critical; your app should continue to work - just that you will have lost any existing session information. If you were hoping to do a hot-deploy, then this would cause it to fail.

Looks like that auto-deploy stuff is not compatible with
ContextApplication
and deserialization. In a nutshell, the problem is that it’s trying to initialize the Spring application context outside of any Vaadin HTTP request thread. Because there’s no Vaadin HTTP request, there’s no way to know which Vaadin
Application
we’re talking about. Obviously you need to know that to initialize the associated Vaadin Spring application context.

This might actually work someday in Vaadin 7.x if they ever fix
Issue #9953
.

Hi,
thanks for your answer.

I’m afraid we can’t switch to Vaadin 7 for the time being :frowning: Is there any way to fix this? I realized that my auto-deploy method dosn’t do anything fancy - it simply redeploys the application and restarts the server, so in production the error will occur as well, won’t it? As soon, as the server has to be restarted, and there are any applications serialized into session, all of them will be invalidated, since they won’t be able to instantiate their “private” Spring context.

…or am I wrong? :slight_smile:

I’m not sure whether or how it can work. It may be that in production you will not see this problem… why go ahead and try it?

I don’t serialize any Vaadin sessions in my normal work so it’s not something I’m familiar with.

If somehow you can get the deserialization to happen within an invocation of
ContextApplication.invoke()
, then that will fix the problem. Not sure how to do that though with your auto-deploy stuff.

Hi,
I’m having trouble wiring spring resources in my application using the springstuff addon. I used a existing backend and I’m building the frontend with Vaadin7. (Spring 3.1.1)
When I define my service like this:


@Resource(name="toestelOpstellingService")
private IToestelOpstellingService toestelOpstellingService;

My service is null.

When using


ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/metadblucht.spring.xml");
toestelOpstellingService = (IToestelOpstellingService) applicationContext.getBean("toestelOpstellingService")

its works but I want to use the annotations.

The services are annotated with @Service(“serviceName”)

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_3_0.xsd" 
id="WebApp_ID" version="3.0">
 
	
	
	<!--  Spring Context -->
	<listener> 
	  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>  
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/metadblucht.xml</param-value>
	</context-param>
	
<!-- 	 Spring Security -->
<!-- 	<filter> -->
<!--         <filter-name>springSecurityFilterChain</filter-name> -->
<!--         <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> -->
<!--     </filter> -->
<!--     <filter-mapping> -->
<!--         <filter-name>springSecurityFilterChain</filter-name> -->
<!--         <url-pattern>/*</url-pattern> -->
<!--     </filter-mapping> -->
    
    <!-- Vaadin Servlet -->
    <servlet>
	  	<servlet-name>metadblucht</servlet-name>
	  	<servlet-class>org.dellroad.stuff.vaadin7.SpringVaadinServlet</servlet-class>
	  	<init-param>
	  		<description>Vaadin UI to display</description>
			<param-name>UI</param-name>
	  		<param-value>be.vmm.lucht.gui.MetadbluchtUI</param-value>
	  	</init-param>
  </servlet>
	  <servlet-mapping>
	  	<servlet-name>metadblucht</servlet-name>
	  	<url-pattern>/*</url-pattern>
	  </servlet-mapping>
	  <servlet-mapping>
	    <servlet-name>metadblucht</servlet-name>
	    <url-pattern>/VAADIN/*</url-pattern>
	</servlet-mapping>
    
    
    
   <!-- Spring Dispatcher Servlet -->
<!--     <servlet> -->
<!--         <servlet-name>dispatcher</servlet-name> -->
<!--         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> -->
<!--         <init-param> -->
<!--         	<param-name>contextConfigLocation</param-name> -->
<!--         	<param-value>classpath:metadblucht-web.spring.xml</param-value> -->
<!--         </init-param> -->
<!--         <load-on-startup>2</load-on-startup> -->
<!--     </servlet> -->
<!--      <servlet-mapping> -->
<!--     	<servlet-name>dispatcher</servlet-name> -->
<!--     	<url-pattern>/servlet/*</url-pattern> -->
<!--     </servlet-mapping> -->
    
    
    
   <resource-ref>
    <description>Database Connection Pool</description>
    <res-ref-name>jdbc/metadblucht</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
  </resource-ref>
  <resource-ref>
    <description>Database Connection Pool</description>
    <res-ref-name>jdbc/security</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
  </resource-ref>
  <resource-ref>
    <description>Database Connection Pool</description>
    <res-ref-name>jdbc/config</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
  </resource-ref>
  
  <display-name>Metadblucht-Vaadin</display-name>
  <context-param>
  	<description>Vaadin production mode</description>
  	<param-name>productionMode</param-name>
  	<param-value>false</param-value>
  </context-param> 
     
  
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
</web-app>

metadblucht.xml


<?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:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-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/aop 
       http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
       
	<context:annotation-config />	
	<context:component-scan base-package="be.vmm" />
	
	<!-- Our application inherits transactions, and auditing from the VMM corelib configuration -->
	<import resource="classpath:core-auditing.spring.xml"/>
	<import resource="classpath:core-transaction.spring.xml"/>
	<import resource="classpath:core-config.spring.xml"/>
	
	<import resource="dao.spring.xml" />
	<import resource="metadblucht-auditing.spring.xml" />
	<import resource="metadblucht-security.spring.xml" />
	
	<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" /> 
    <bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" /> 
	
	
</beans>

Some thoughts…

Try adding
@Required
to your
@Resource
, or switch to
@Autowired
so it can’t be left null without an error.

You shouldn’t manually add those two
BeanPostProcessors
because
context:annotation-config/
does that for you.

It looks like you are using
metadblucht.xml
as both the servlet-scope application context and the
VaadinSession
-scope application context. This is wrong. You should define two separate application contexts, and the latter should have its location defined using the
configLocation
servlet
init-param
.

See the demo web application for an example.

Ty for your reply.

I changed the web.xml to


<!--  Spring Context -->
	<listener> 
	  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>  
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:metadblucht.xml</param-value>
	</context-param>
    
	<!--     Vaadin Servlet -->
    <servlet>
	  	<servlet-name>MetadbluchtVaadin</servlet-name>
	  	<servlet-class>org.dellroad.stuff.vaadin7.SpringVaadinServlet</servlet-class>
	  	<init-param>
			<param-name>UI</param-name>
	  		<param-value>be.vmm.lucht.gui.MetadbluchtUI</param-value>
	  	</init-param>
	  	<init-param>
	  		<param-name>configLocation</param-name>
			<param-value>classpath:MetadbluchtVaadin.xml</param-value>
	  	</init-param>
	  	 <init-param>
            <param-name>productionMode</param-name>
            <param-value>false</param-value>
        </init-param>
  	</servlet>
	  <servlet-mapping>
	  	<servlet-name>MetadbluchtVaadin</servlet-name>
	  	<url-pattern>/*</url-pattern>
	  </servlet-mapping>   

metadblucht-vaadin.xml contains only context:annotation-config/
metadblucht.xml same content as in previous post except for the two beanPostProcessors

VaadinServlet.getCurrent().getServletContext() return metadblucht.xml ← shouldnt this be metadblucht-vaadin.xml?

I deployed demo3 (eclipse 4.2, spring 3.1.1, tomcat 7.0.39) and I have the same problem
SEVERE:
java.lang.NullPointerException
at com.example.HelloUI.init(HelloUI.java:75)

Not sure what you mean.
getServletContext()
returns a
ServletContext
object, not an application context.

In any case, it is correct that the
metadblucht.xml
application context is associated with the servlet context, while the
MetaBluchtVaadin.xml
application context is associated with the
VaadinSession
.

I just tried building and running the dellroad-stuff-vaadin-spring-demo3 using Spring 3.1.x and it worked fine.

Try building it using the supplied ant
build.xml
file. I bet Eclipse is not running the AJC compiler.

Hi Archie,
I made the changes but got the same result, still NPE

I am attaching (eclipse export) a stripped version of the application if you could take a look at it.
13009.zip (109 KB)

If I had more time I would be happy to help you debug further. Unfortunately I don’t, sorry.

My only suggestion is to try to figure out how your app and the demo app are different.

Hi,

Could you post an example project for Vaadin 7, too.

It’s already there as part of the same github project. Just switch to the
vaadin7
branch.

Hi, Archie.

Is there any particular reason why org.dellroad.stuff.vaadin7.VaadinApplication is not implementing Serializable?

No. I don’t use serialization myself so the need hasn’t come up. It should be easy to add.

Do you happen to have a patch handy that you have tested out?

-Archie

Archie, not currently, but I will work on one this week. It is not a big issue, I just don’t want my Tomcat production instance administrator to be scared by some random exceptions :slight_smile:

Hi Archie, I used your great addon successfully with Vaadin 6. But now I have to move to Vaadin 7. Is is supposed to work with 7.1.3? I cannot get it to work. I tried your sample application on github but that gives me an NPE in HelloUI when trying to access the HelloWorld bean, which should have been autowired at this point.
And by the way, how could I use the whole thing without autowiring? I prefer using the traditional approach via XML only and I have no idea how the UI class could get it’s properties then.
Best Regards
Ralph