Java Serializable and serialVersionUID

January 14th, 2010 by nils

Here’s a question:

Is a serialVerionUID required on abstract classes?

My first thought: No way! If the serialVersionUID is used by the serialization mechanism to check whether some serialized data is compatible with a serializable class, abstract classes (that will never be instantiated, and thus, never be serialized directly) don’t need one! The problem is that the entire inheritance tree is checked when a class is de-serialized — and that includes abstract base classes. A simple example illustrates the problem:

If we have an abstract base class …

import java.io.Serializable;

public abstract class Base
implements Serializable {}

… and a sub-class that declares a serialVersionUID …

public class Sub extends Base {
    private static final long serialVersionUID =
      -7913545780181427623L;
}

… and we create an instance of the sub-class and serialize it to a file …

...
Sub sub1 = new Sub();
try {
    FileOutputStream fout = new FileOutputStream("sub.dat");
    ObjectOutputStream oos = new ObjectOutputStream(fout);
    oos.writeObject(sub1);
    oos.close();
} catch (Exception e) {
    e.printStackTrace();
}

… and then we change the base class by e.g. adding an int field …

import java.io.Serializable;

public abstract class Base
implements Serializable {
    int a = 0;
}

… and try to de-serialize the sub-class …

Sub sub2 = null;
// Load the file and de-serialize the object
try {
    FileInputStream fin = new FileInputStream("sub.dat");
    ObjectInputStream ois = new ObjectInputStream(fin);
    sub2 = (Sub) ois.readObject();
    ois.close();
} catch (Exception e) {
    e.printStackTrace();
}

… we’ll get a “java.io.InvalidClassException”.

If we do the same thing, but define a serialVersionUID in the abstract base class, the exception would not occur. The reason for this is, that if a serialVersionUID is not explicitly declared, the JVM will calculate a default one, “based on various aspects of the class” [1]. This is a great mechanism, at first glance it even seems to be better than creating the id manually — if the class changes, these changes are automatically reflected in the generated id. But, this mechanism can differ based on the VM If you would run this example on one VM and then try to de-serialize the same “sub.dat” file with a different VM, without modifying the base class, it is possible that you would get an “InvalidClassException”, simply because the VM uses a different mechanism to calculate the default serialVersionUID. This is why it is recommended to manually declare the serialVersionUID.

However, this also means that, if we change a serializable class and thereby make it incompatible with previously serialized instances, we have to update the serialVersionUID!

Now if we think about software maintenance and data integrity, there should be a way to migrate existing serialized data to new versions of the serializable class. I’d be interested to know if there is an official recommendation for this, but didn’t investigate further yet.

It would also be interesting to see how OR-mapping frameworks fit into the picture. There is an interesting thread on using Serializable and what to do with the serialVersionUID in the hibernate JIRA: http://opensource.atlassian.com/projects/hibernate/browse/HBX-964

I’d be interested to know what others think about this, so please feel free to comment!

[1] http://java.sun.com/javase/6/docs/api/java/io/Serializable.html

jBPM 4.3 and Spring

January 6th, 2010 by nils

jBPM has just been released in version 4.3 and the spring integration has been changed. If you used to have an application that uses the spring integration of previous versions of jBPM, this might lead to exceptions like this:

org.springframework.beans.factory.BeanCurrentlyInCreationException:
Error creating bean with name 'repositoryService': Requested bean
is currently in creation: Is there an unresolvable circular
reference?

The problem is that rather than having to declare all of jBPM’s services in your application context — like it used to be up to jBPM 4.2 —, the new spring integration provides access to them through the Process Engine. All you need in your application context is this:

<bean id="springHelper">
  <property name="jbpmCfg" value="PATH TO YOUR jbpm.cfg.xml">
</property>
</bean>
<bean id="processEngine" factory-bean="springHelper"
factory-method="createProcessEngine" />

Now you can inject the processEngine into your classes and retrieve jBPM’s services like this:

processEngine.getExecutionService() …
processEngine.getRepositoryService() …
…