Java IO Tutorial

Java – What is serialVersionUID

In Java, serialVersionUID is something like version control, assure both serialized and deserialized objects are using the compatible class.

For example, if an object saved into a file (Serialization) with serialVersionUID=1L, when we convert the file back to an object (Derialization), we must use the same serialVersionUID=1L, otherwise an InvalidClassException is thrown.

Terminal

Exception in thread "main" java.io.InvalidClassException: com.mkyong.io.object.Address;

    local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2

1. POJO

Review a simple Address class, implements Serializable, and declared a serialVersionUID = 1L.

Address.java

package com.mkyong.io.object;

import java.io.Serializable;

public class Address implements Serializable {

    private static final long serialVersionUID = 1L;

    String street;
    String country;

    public Address(String street, String country) {
        this.street = street;
        this.country = country;
    }

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    @Override
    public String toString() {
        return "Address{" +
                "street='" + street + '\'' +
                ", country='" + country + '\'' +
                '}';
    }
}

2. Test SerialVersionUID.

2.1 Save an object into a file, and convert it back from the file to an object.

ObjectUtils.java

package com.mkyong.io.object;

import java.io.*;

public class ObjectUtils {

    public static void main(String[] args) throws IOException, ClassNotFoundException {

        Address address = new Address("abc", "Malaysia");

        // object -> file
        try (FileOutputStream fos = new FileOutputStream("address.obj");
             ObjectOutputStream oos = new ObjectOutputStream(fos)) {
            oos.writeObject(address);
            oos.flush();
        }

        Address result = null;
        // file -> object
        try (FileInputStream fis = new FileInputStream("address.obj");
             ObjectInputStream ois = new ObjectInputStream(fis)) {
            result = (Address) ois.readObject();
        }

        System.out.println(result);

    }

}

Output

Terminal

  Address{street='abc', country='Malaysia'}

2.2 Update the serialVersionUID to 99L.

Address.java

public class Address implements Serializable {

    private static final long serialVersionUID = 99L;

    String street;
    String country;
    //...

Rerun the deserialization process.


  Address result = null;
  // file -> object
  try (FileInputStream fis = new FileInputStream("address.obj");
       ObjectInputStream ois = new ObjectInputStream(fis)) {
      result = (Address) ois.readObject();
  }

  System.out.println(result);

Now, we hit InvalidClassException.

Terminal

Exception in thread "main" java.io.InvalidClassException: com.mkyong.io.object.Address;

  local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 99

  at java.base/java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:689)
  at java.base/java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1903)
  at java.base/java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1772)
  at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2060)
  at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1594)
  at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:430)

3. When should I update the serialVersionUID?

When we modify a class that will break the compatibility with the existing serialized object, for example, we update the current Address class, with some fields added and removed.

This new changed will failed all the existing serialized objects, then we should update the serialVersionUID.

Address.java

public class Address implements Serializable {

    private static final long serialVersionUID = 9999L;

    String line1;
    String line2;
    Country country;

    //String street;
    //String country;
}

4. Default serialVersionUID?

If no serialVersionUID is declared, JVM will use its algorithm to generate a default SerialVersionUID, 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.

Review the following example:

Client / Server environment
– The client is using OpenJDK on Windows.
– The server is using GraalVM On Linux.

The client sends the serialized class with SerialVersionUID=1L to the server. The server may deserialize the class with a different serialVersionUID=99L, and throws InvalidClassExceptions. Since both are using different JVM implementation, it might generate a different SerialVersionUID on both sites.

There are many JVM implementation

Download Source Code

$ git clone https://github.com/mkyong/core-java.git

$ cd java-io

References

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
35 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
Hemalatha Kandagiri
7 years ago

I understood a bit. My doubt is, But I am not sure. can two different classes like class A and Class B can have same serialize ID? Pelase correct me if my question is wrong

qiao pan ma
5 years ago

i think it is true, since i sometimes put different class with 1L . but i don`t know what is the disadvantage if two classes share one serialize id?

koma
9 years ago

why “serialVersionUID” should be lower case when it’s a constant?

Rakesh Yadav
10 years ago

Hi Mr yong, its very easy and nice example to understand serialVersionUID,
I appreciate your work and thanks for sharing.

*************************************************************************************

We are generating a web based application, as part of this we need to use a number of Applets. But the problem is again with serialVersionUID.

java.io.InvalidClassException: XYZ local class incompatible: stream classdesc serialVersionUID = -962022720109015502, local class serialVersionUID = 532615968316031794

Here the problem is we need to use predefined class, where I can’t change serialVersionUID (my assumption). and as this is the web based application, I’m not supposed to force all my clients to use specific JRE.

Please suggest me the solution for this, my complete project was struck at this point. Please help me
– Thanks in advance

Samella Geiser
11 years ago

I do believe all of the ideas you’ve introduced to your post. They are really convincing and can certainly work. Nonetheless, the posts are too quick for beginners. May just you please extend them a little from subsequent time? Thanks for the post.

sujaan kumar
7 years ago

Hi mkyoung,
very good explanation.
As we know that serializable is a marker interface it doesn’t contain any method or variable ,when we are not define the serialVersionUID explicitly then JVM put a default one.my question is from where this static final variable comes from.

infoj
6 years ago
Reply to  sujaan kumar

The stream-unique identifier is a 64-bit hash of the class name, interface class names, methods, and fields.
Also from Java docs – http://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html
If a serializable class does not explicitly declare a serialVersionUID, then the serialization runtime will calculate a default serialVersionUID value for that class based on various aspects of the class, as described in the Java(TM) Object Serialization Specification. However, it is strongly recommended that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations

Deepak Pandey
8 years ago

serialversionUID is static does it also serialize with class. if YES then how it can get serialize as it is static field , it is not stored on heap so its not related to object but related to class. If NO then how jvm finds that the class we are deserialize is same . Please explain working of SerialiversionUID. Thanks in advance

Deepak Pandey
8 years ago
Reply to  Deepak Pandey

Please explain If anyone have answer to this question

rajneekanth
8 years ago

good one.

Raj Parekh
8 years ago

Very well explained. Thank you.

Zia Ulhaq
8 years ago

i have a question.. can i initiate any value for serialVersionUID ?

ggsongnail
10 years ago

I have question “Unknown column ‘serialVersionUID’ in ‘order clause'” how to solve it? thx

merlin
11 years ago

Hi, mkyong, I have read a lot of your technical blogs about java, and they really help me so much. I post this comment just to express my appreciation, thank you very much.

Nitin
11 years ago

Thanks yong it is very useful content.

Kamal Giri
11 years ago

Thank you MKYONG for Sharing this tutorial.

prashanth
11 years ago

Hi,
In my project there are 100’s of Classes are derived from Serializable interface, but serialVersionUID not used manually. Till now its working fine. Now its giving the java.io.InvalidClassException. I am unable change all my existing classes.

Please tell me the solution with out adding serialVersionUID manually how to solve this problem.

Thanks in advance.

Regards,
Prashnath

sarath
11 years ago
Reply to  prashanth

it may be because of you have made few edit in the code..
redo all it will solve your problem i think.

Sebastian
11 years ago

@mkyong

Thanks for your work on this blog. Each time I have a doubt with Java I end up here and resolving my issue ALWAYS. Thanks again!

Zaf
11 years ago

Thanx for ur description, its helpful 🙂

Amol Dake
11 years ago

your site is really very helpful,I appreciate your work…

Janak Porwal
11 years ago

Thanks…. simple, neat explanation with good advice.

krisha
12 years ago

uhm, since i am still studying i am not yet familiar with everything in making programs .. i just wanna ask BOUT HOW WILL I EXPLAIN IF I USED serialVersionUID in my program?

y s rao
12 years ago

Hi Thanks. nice explanation.

What i understand from your explanations is : the serial version id should be same for the class while serialization / de-serialization. If so, why java people left this to the developers. why they did not assigned some constant value (by default) to each and every class that we create, instead of assigning the value by some calculation?.

Thanks
Y S Rao

yuyuchen09
10 years ago
Reply to  y s rao

When there is enough changes that should honor an new version. That gives developer the option to invalidate the older version already installed, and make it incompatible.

Sandeep
13 years ago

That saved the day for me. 🙂

Artur Biesiadowski
14 years ago

@cjiang
Java serialization is a more efficient than automatic xml serialization – in each of processing memory, wire usage and cpu usage to encode and decode. For manual xml serialization, you can also expect it to be considerably faster.
Said that, there are other ways to be even faster than that – for example take a look at Hessian http://hessian.caucho.com/

As far as serializing/deserializing on different JVMs is concerned, I thought that this issue was mainly tied to different compilers, which can create different synthetic methods. For same binary class file, serialVersionUID should be deterministic AFAIK ? Maybe mkyong can provide us with exact scenario when it can happen, if all classes have same byte representations…

@mkyong
I personally prefer to just put serialVersionUID = 1, instead of using any of the generators. It is same good, nicely represents version of class if we ever would like to do incompatible change. Only case where I use automatic generation is to interface with existing system where somebody forgotten to specify it explicitly – but even then, it is easier to retrieve it from exception 🙂

cjiang
14 years ago

Artur,
Thank you for the reply.

cjiang
14 years ago

Need your help with two questions.
1) Are all jvm implementations always confirming to the java serialization spec? ie. if I serialize a Java object in sun jvm, can I always be able to deserialize it in JRocket or IBM’s jvm providing the serialVersionUID is the same?
2) Will serialization form using java serializable mechanism consume more memory than using xml representation?

Thanks.

Tao
11 years ago
Reply to  mkyong

Hi mkyong,

grazie mille per te

JVM
4 years ago
Reply to  Tao

bruh, what the fk you are talking about

afon
14 years ago

Good and interesting explanation. thanks.