Java Serialization Versioning with Externalizable

Uncategorized - 1 Comment » - Posted on October, 22 at 1:39 am

Java Serialization is a easy way to persist the state of Java Objects. However if the structure of the class changes the serialized bytes is invalidated by the changes. This article suggest how one could implement serialization with Externalizable with support for versions.

Consider a simple java class

  1. public class SimpleObject implements Serializable {
  2.         private int field1;
  3.         private int field2;
  4. }

If the structure of the class changes, then the serialized bytes becomes incompatible and you would get the dreaded ClassCastException

  1. public class SimpleObject implements Serializable {
  2.         //private int field1; removed
  3.         private int field2;
  4.         private int field3; //added
  5. }

A good way to get complete control of the serialization and support version is by implementing Externalizable instead of Serializable.

Externalizable gives the programmer full control over how the class is serialized and de-serialized. It is common practice to add a version variable to support representations of the same class over time.

Consider first version of the same class

  1. public class SimpleObject implements Externalizable {
  2.         private int version=1;
  3.         private int field1;
  4.         private int field2;
  5.         @Override
  6.         public void readExternal(ObjectInput in) throws IOException,
  7.                         ClassNotFoundException {
  8.                 version=in.readInt();
  9.                 if(version==1) {
  10.                         field1=in.readInt();
  11.                         field2=in.readInt();
  12.                 } else {
  13.                         throw new IOException(“Invalid Version”);
  14.                 }
  15.         }
  16.         @Override
  17.         public void writeExternal(ObjectOutput out) throws IOException {
  18.                 out.writeInt(version);
  19.                 out.writeInt(field1);
  20.                 out.writeInt(field2);
  21.         }
  22. }

Now if the next version of the class needs to add a String and remove field2 the class would look like

  1. public class SimpleObject implements Externalizable {
  2.         private int version=2;
  3.         private int field1;
  4.         //private int field2; removed
  5.         private String version2String;
  6.         @Override
  7.         public void readExternal(ObjectInput in) throws IOException,
  8.                         ClassNotFoundException {
  9.                 version=in.readInt();
  10.                 if(version==1) {
  11.                         field1=in.readInt();
  12.                         in.readInt();// ignore
  13.                         version2String=“”;// initialize to default
  14.                 } else if (version==2) {
  15.                         field1=in.readInt();
  16.                         version2String=(String) in.readObject();
  17.                 } else {
  18.                         throw new IOException(“Invalid Version”);
  19.                 }
  20.         }
  21.         @Override
  22.         public void writeExternal(ObjectOutput out) throws IOException {
  23.                 out.writeInt(version);
  24.                 out.writeInt(field1);
  25.                 out.writeObject(version2String);
  26.         }
  27. }

Posted in Uncategorized | 1 Comment »

One Response to “Java Serialization Versioning with Externalizable”

  1. Ramakrishnan says:

    In the second version, the version number is still 1 which may be confusing.

Leave a Reply