Newsletter sign-up
View all newsletters

Sign up for our technology specific newsletters.

Enterprise Java
Email Address:

Ensure proper version control for serialized objects

Java serialization and version control for release compatibility

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone

Page 2 of 6

  1. That changes to a serializable class result in a different computed suid.
  2. How the Java serialization mechanism matches the suid in the current version of the serializable class with the value saved in the object serialized with the class's prior version. This approach provides Java serialization its version control mechanism.


 java.io.InvalidClassException: MySerializableClass; Local class not compatible: stream classdesc serialVersionUID=7187368850772554122  local class serialVersionUID=4104486680721271886
at java.io.ObjectStreamClass.validateLocalClass(ObjectStreamClass.java:565)
at java.io.ObjectStreamClass.setClass(ObjectStreamClass.java:609)
at java.io.ObjectInputStream.inputClassDescriptor(ObjectInputStream.java:981)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:402)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:272)
at java.io.ObjectInputStream.inputObject(ObjectInputStream.java:1231)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:422)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:272)
at MyDeserializeClient.main(MyDeserializeClient.java:27)



The suid is set in one of two ways, with the first being the default mechanism described above. The Java serialization mechanism automatically computes a hash value. ObjectStreamClass's computeSerialVersionUID method passes the class name, sorted member names, modifiers, and interfaces to the secure hash algorithm (SHA), which returns a hash value. This computation technique ensures that most changes in an object's "shape" and attribute types result in different hash values. I elaborate on the significance of this default suid generation later when I discuss release compatibility.

In the second approach, the developer explicitly sets suid in the serializable class, as shown in the code below:

 package java.io;
public class MySerializableClass implements Serializable {
   private static final long serialVersionUID = 1999L;

static String notSerializableString = "static field not serialized"; transient Thread T1; /* Transient field not serialized */

public int aNum = 0; public String serializedString = "a serialized string";

private void writeObject (ObjectOutputStream s) throws IOException { s.defaultWriteObject (); // Followed by customized serialization code }

private void readObject (ObjectInputStream s) throws IOException, ClassNotFoundException { s.defaultReadObject (); // Followed by customized deserialization code } }


A developer can set the suid with any integer value. However, a developer can also pass the class name to a Java command—serialver—which computes a hash value using the same algorithm described above. The developer then pastes the return value into the source code. In the following sections, I discuss why it is important for the developer of a serializable class to explicitly set the suid in the code.

Evolution of a serializable class

Changes to a serializable class can be either compatible or incompatible. A compatible change results in the evolved class being able to deserialize objects serialized by the class of a prior release. Conversely, the object serialized by the evolved class can be deserialized by the class's prior version. Compatible changes typically result from adding fields or objects to the object graph. With the addition of fields or objects, the default Java serialization read-mechanism simply provides default values for the corresponding attribute types. Examples of compatible changes are the following:

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comment
Login
Forgot your account info?
Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources