Sometimes when a object is serialized at one server and deserialized at other server i.e on different JVMs , deserialization may fall and you can come across InvalidClassException . This seems to be quite weird. Right? This post is aimed at explaining the root cause of this issue and what should be the better approach while implementing serialization . You can refer to my other blog on Serialization where we have learnt the serialization mechanism and how to implement serialization in Java to get started on serialization.
Basically , when we serialize any object , the class metadata is also saved along with object's state which is used while that object is deserialized. One thing that is part of this metadata is serialVersionUID . In my previous post , I told you that it is used for versioning. We will now see what does it actually mean . You must have seen that whenever you implement serializable interface , compiler gives you warning to generate serialVersionUID(suid):
Serializable Class |
You can either generate it using the options provided by compiler or there is a jdk utility - serialver which can also be used for the same purpose.
Even in case you do not generate it, it is automatically generated by JVM for the serializable class based on the class metadata information and is saved while serialization.When you try deserializing the object , suid of current class is matched to the suid present in metadata information of serialized object . In case they match object is deserialized otherwise InvalidClassException is thrown . Let me illustrate on this with below code :
I hope this post gives you enough understanding about the significance of serialVersionUID and the impacts of having a default and generated serialVersionUID.
Even in case you do not generate it, it is automatically generated by JVM for the serializable class based on the class metadata information and is saved while serialization.When you try deserializing the object , suid of current class is matched to the suid present in metadata information of serialized object . In case they match object is deserialized otherwise InvalidClassException is thrown . Let me illustrate on this with below code :
- Serialization Phase: We will create a Serializable class with a serialVersionUID (4311891935872630973L) and then we will serialize a object of this class in our TestSerialization Main Class .
Serializable class TestSerialization Main Class Console Output - Deserialization Phase : serialVersionUID of the Serializable class is updated to 4311891935872630974L and serialized object is being deserialized.
Serializable class TestSerialization Main Class
Output : java.io.InvalidClassException: org.tech.model.SerializableStudent; local class incompatible: stream classdesc serialVersionUID = 4311891935872630973, local class serialVersionUID = 4311891935872630974Console Output
Since we have got the concept of suid, we need to understand the significance of user generated suid . This is because in a multi-system environment , where you are serializing on one JVM and deserializing on other , a default JVM generated suid can lead to InvalidClassException because each JVM has its own implementation and configuration so different JVM can generate different suid for same serializable class.
I hope this post gives you enough understanding about the significance of serialVersionUID and the impacts of having a default and generated serialVersionUID.
Nice
ReplyDelete