Thursday, May 22, 2014

Why use SerialVersionUID inside Serializable class in Java

Serialization and SerialVersionUID is always remains a puzzle for many Java developers. I often see questions like what is this SerialVersionUID, or what will happen if I don't declare SerialVersionUID in my Serializable class? Apart from complexity involved and rare use, one more reason of these questions is Eclipse IDE's warning against absence of SerialVersionUID e.g. "The Serializable class Customer does not declare a static final SerialVersionUID field of type long". In this article, you will not only learn basics of Java SerialVersionUID but also it's effect during serialization and de-serialization process. When you declare a class as Serializable by implementing marker interface java.io.Serializable, Java runtime persist instance of that class into disk by using default Serialization mechanism, provided you have not customized the process using Externalizable interface. During serialization, Java runtime creates a version number for a class, so that it can de-serialize it later. This version number is known as SerialVersionUID in Java. If during de-serialization, SerialVersionUID doesn't match than process will fail with InvalidClassException as  Exception in thread "main" java.io.InvalidClassException, also printing class-name and respective SerialVersionUID. Quick solution to fix this problem is copying SerialVersionUID and declaring them as private static final long constant in your class. In this article, we will learn about why we should use SerialVersionUID in Java and How to use serialver JDK tool for generating this ID. If you are new to serialization, you can also see Top 10 Java Serialization Interview question to gauge your knowledge and find gap in your understanding for further reading. Similar to Concurrency and Multi-threading, Serialization is another topic, which deserve couple of reading.



Why use SerialVersionUID in Java

As I said, when we don't declare SerialVersionUID, as a static, final and long value in our class, Serialization mechanism creates it for us. This mechanism is sensitive to many details including fields in your class, there access modifier, the interface they implement and even different Compiler implementations, any change on class or using different compiler may result in different SerialVersionUID, which many eventually stop reloading serialized data. It's too risky to rely on Java Serialization mechanism for generating this id, and that's why it's recommended to declare explicit SerialVersionUID in your Serializable class. I strongly suggest to read Joshua Bloch's classic Java title, Effective Java to understand Java Serialization and issues of incorrect handling it. By the way JDK also provides a tool called serialver, located in bin directory of JAVA_HOME folder, in my machine C:\Program Files\Java\jdk1.6.0_26\bin\serialver.exe, which can be used to generate SerialVersionUID for old classes. This is very helpful, in case you have made changes in your class, which is breaking Serialization and your application is not able to reload serialized instances. You can simply use this tool to create SerialVersionUID for old instances and then use it explicitly in your class by declaring a privatestaticfinal and long SerialVersionUID field. By the way, it's highly recommend, both due to performance and security reason to use customized binary format for Serialization, once again Effective Java has couple of Items, which explains benefits of custom format in great details.


How to use serialver JDK tool to generate SerialVersionUID

You can use JDK's serialver tool to generate SerialVersionUID for classes. This is particularly useful for evolving classes, it returns SerialVersionUID in format easy to copy. You can use serialver JDK tool as shown in below example :

$ serialver
use: serialver [-classpath classpath] [-show] [classname...]

$ serialver -classpath . Hello
Class Hello is not Serializable.

$ serialver -classpath . Hello
Hello:    static final long SerialVersionUID = -4862926644813433707L;

You can even use serialver tool in GUI form by running command  $ serialver -show, this will open the serial version inspector, which takes full class name and shows it's Serial version.


Summary

Now we know what is SerialVersionUID and why it's important to declare it in Serializable class, it's time to revise some of the important fact, related to Java SerialVersionUID.

1) SerialVersionUID is used to version serialized data. You can only de-serialize a class if it's SerialVersionUID matches with the serialized instance.

2) When we don't declare SerialVersionUID in our class, Java runtime generates it for us, but that process is sensitive to many class meta data including number of fields, type of fields, access modifier of fields, interface implemented by class etc. You can find accurate information in Serialization documentation from Oracle.

3) It's recommended to declare SerialVersionUID as private static final long variable to avoid default mechanism. Some IDE like Eclipse also display warning if you miss it e.g. "The Serializable class Customer does not declare a static final SerialVersionUID field of type long". Though you can disable this warnings by going to Window > Preferences > Java > Compiler > Errors / Warnings > Potential Programming Problems, I suggest not to do that. Only case, I see being careless is when restoring of data is not needed. Here is how this error looks like in Eclipse IDE, all you need to do is accept first quick fix.

What is SerialVersionUID in Java and Why you need it





4) You can even use serialver tool from JDK to generate Serial Version for classes in Java. It also has a GUI, which can be enable by passing -show parameter.

5) It's Serialization best practice in Java to explicitly declare SerialVersionUID, to avoid any issues during de-serialization especially if you are running a client server application which relies on serialized data e.g. RMI.

That's all about SerialVersionUID in Java. Now we know that Why it's important to declare SerialVersionUID right into the class. You can thanks your IDE for this reminder, which may potentially break de-serialization of your class.

If you want to learn more about Serialization and related concept, you can also see these amazing articles :
Difference between transient and volatile variable in Java
Difference between Serializable and Externalizable interface in Java
When to use transient variable in Java

3 comments :

Anonymous said...

Hi Sir,
I have learned more from this blog than from any other Source I have ever had. thanks a lot for your help

here,my humble request is, please try to organise your posts topic wise , so it will be even more helpful for the people like me

thanks once again

Prithviraj said...

Thank you very much for your thoughts on this topic. Your blog has always been helpful for all java developers.
So from this topic I also understand that, whenever you are writing new serializable class, we should use serialver tool to generate SerialVersionUID. And then put this gendered UID, in your serializable class. This will not create any issues further in serialization/de-serialization process.
Please let me know if my understanding is correct.

Anonymous said...

Is it possible that two classes contain similar SerialVersionUID ?. If such a situation occurs, will it cause any issues during de-serialization process ?.

Post a Comment