Guide to understanding of serialVersionUID

1. Overview

In this guide, we will understand the usage of serialVersionUID in Serialization.
This was the one of the interview question asked for me like what is the use of
serialVersionUID in Serialization ?
In this post I would like to explain the usage of the serialVersionUID with examples. 
You may also read top post : Secure Coding Standards for Java Serialization
Important: The serialVersionUID have to match during the serialization 
           and deserialization process.
The serialVersionUID is used as a version control in a Serializable class. If you do not explicitly declare a serialVersionUID, JVM will do it for you automatically, based on various aspects of your Serializable class, as described in the Java(TM) Object Serialization Specification.

2. Serialization with serialVersionUID Example

let's create an example to understand how Serializable class uses serialVersionUID to implement version control.
Let's create an Employee class with a serialVersionUID = 2L.
Example:
class Employee implements Serializable {
 private static final long serialVersionUID = 2L;
 private int id;
 private String name;

 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }
}
Now write the code to serialize the employee object.
In the example, serializeProcessing() method perform serialization and write the employee object to employee.txt file.
public class SerializationWithSerialVersionUID {

 public static void main(String[] args) throws IOException, ClassNotFoundException {
  final Employee employee = new Employee();
  employee.setId(100);
  employee.setName("ramesh");
  serilizeProcessing(employee);
 }

 private static void serializeProcessing(Employee employee)
   throws IOException {
  final FileOutputStream fout = new FileOutputStream("employee.txt");
  final ObjectOutputStream out = new ObjectOutputStream(fout);
  out.writeObject(employee);
  out.flush();
  System.out.println("success");
 }
}

3. De-serialization Example

A simple class to deserialize the Employee class object from file – “c:\employees.txt” file.
In the example, deSerializeProcessing() method perform deserialization.
public class DeserializationWithSerialVersionUID {

 public static void main(String[] args) throws IOException, ClassNotFoundException {
  final Employee employee = new Employee();
  employee.setId(100);
  employee.setName("ramesh");
  deSerializeProcessing();
 }

 
 private static void deSerializeProcessing() throws IOException, ClassNotFoundException {
  final ObjectInputStream in = new ObjectInputStream(new FileInputStream(
    "employees.txt"));
  final Employee employee = (Employee) in.readObject();
  System.out.println(" printing employee object details");
  System.out.println(employee.getId() + " " + employee.getName());
  in.close();
 }

}

4. Demonstrating the use of serialVersionUID

Let do some testing to demonstrate the use of serialVersionUID. 

Same serialVersionUID

If there is same serialVersionUID, then no problem during the deserialization process. Output:
100 ramesh

Different serialVersionUID

In Employee.java, change the serialVersionUID to 3L (it was 2L), and compile it again. Compiler will throw an exception as:
java.io.InvalidClassException: Employee; local class incompatible: 
stream classdesc serialVersionUID = 2, local class serialVersionUID = 3
The “InvalidClassException” will raise, because you wrote a serialization class with serialVersionUID “2L” but try to retrieve it back with updated serialization class, serialVersionUID “3L”.

5. Explanation

What’s wrong with the default serialVersionUID?

If no serialVersionUID is declared, JVM will use its own algorithm to generate a default SerialVersionUID, you can check the algorithm here.
The default serialVersionUID computation is highly sensitive to class details and may vary from different JVM implementation, and result in an unexpected InvalidClassExceptions during the deserialization process.

Client / Server environment

– Client is using SUN’s JVM in Windows. 
– Server is using JRockit in Linux.
The client sends a serializable class with default generated serialVersionUID (e.g 123L) to the server over socket, the server may generate a different serialVersionUID (e.g 124L) during deserialization process, and raises an unexpected InvalidClassExceptions.

File / Database environment

– App #1 is using SUN’s JVM in Windows.
– App #2 is using JRockit in Linux.
Serialization has allowed saving into a file or database. App #1 stores a serializable class into database by default generated serialVersionUID (e.g 123L), while App #2 may generate a different serialVersionUID (e.g 124L) during deserialization process, and raise an unexpected InvalidClassExceptions.

How to generate serialVersionUID?

You can use JDK “serialver” or Eclipse IDE to generate serialVersionUID automatically, see detail.

6. Conclusion

SUN is highly recommended developers to declare the serialVersionUID in order to avoid the different JVM issue listed above, however I rather recommend you should understand what is serialization and it's best practices how serialVersionUID implement version control and why your class need to use serialization. Understand the serialVersionUID concept is better than blindfold to any recommendation.

7. Related Posts

Comments