Spring, Sessions and Serialization

Hi Vaadin community,

I am struggling with Spring and restoring a Vaadin application from serialized state. I’ll start by giving some background…

In the application I’m developing, I want to be able to inject Vaadin components with Spring beans. Let’s say, for instance, I have a Table; which is backed by a BeanItemContainer, which is in turn backed by a DAO object which is in Spring. This is of course pretty standard stuff; inside Application init(), I would do the following:


public class MyApp extends Application
{

protected transient ApplicationContext springContext;


public void init()
{
ServletContext servletContext = ((WebApplicationContext) this.getContext()).getHttpSession().getServletContext();
springContext = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);

....
}

}

the context is then passed on to the BeanItemContainer, so it can look up the DAO:


...
MyDAO dao = springContext.getBean("myDAO");
...

All this works great, until the application gets serialized and is then restored from serialization. Obviously, the Spring context cannot be serialized; so the ApplicationContext needs to be transient. To ensure that the application can re-acquire the spring content on deserialization; we add the following method:



        //this method is what's actually used to read the object back from the serialized state, per the Serialization API
	private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
	
        //read the object (in this case, the Vaadin application) from serialized state 
        ois.defaultReadObject();
	 

       // now reinstantiate the ApplicationContext since that was not serialized
       ServletContext servletContext  = ((WebApplicationContext)this.getContext()).getHttpSession().getServletContext();
springContext = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
	}

The problem is that at this point, getHttpSession() returns null. So, after deserialization, it’s almost as if the Vaadin application is now detached from the session or fails to re-attach. Since I need the session to be able to get to the SpringContext, I cannot re-instantiate the spring context and so the DAO cannot be reloaded on deserialization.

Any ideas on how to solve this?

Thanks!

Hi,

I’m not very knowledgeable about Spring, even though we’re using it : instead of doing the serialization/deserialisation ourselves, we’re simply using spring’s annotation-based configuration, along with load-time weaving (for development). Instead of asking explicity for the ApplicationContext, we ask for the bean we want to be autowired (although, you can autowire the ApplicationContext if you like. I’ve just tried it).


@Configurable
MyApp extends Application {
  @AutoWired transient  MyDAO dao;
}

The load-time weaver is then in charge of assigning/wiring the dependencies, either at serialize/deseralize time.

I’m sorry it’s a bit sketchy - I’m a bit hazy on the exact details myself - but by doing this, you don’t have to manage the issue yourself.

Cheers,

Charles

Here’s a
stackoverflow.com thread
talking about the same issue.

Basically, what they claim is that in Spring 3.0, if you get beans from a WebApplicationContext then what you really get are proxies that automatically handle serialization and deserialization by storing only the name of the proxied bean when serialized, and then re-finding and re-attaching the proxied bean when deserialized.

So if you use Spring 3.0 then in some sense it should “just work” and you should not have to do anything special.

As a side note, you may want to use my
AutowiringApplicationServlet
to simplify your code little bit and remove the manual wiring.