If you have ever implementedSerializableinterface, you must encounter this warning message
TheserializableclassxxxdoesnotdeclareastaticfinalserialVersionUIDfieldoftypelong
intro. So…what is serialVersionUID?
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 theJava(TM) Object Serialization Specification.
1. SerialVersionUID Example
The above statement is a bit hard to understand at the beginning (at least I did), let start an example to understand how Serializable class use SerialVersionUID to implement version control.
1.1 Address.java
A serializable class with a serialVersionUID of 1L.
importjava.io.Serializable;
publicclassAddressimplementsSerializable{
privatestaticfinallongserialVersionUID=1L;
Stringstreet;
Stringcountry;
publicvoidsetStreet(Stringstreet){
this.street=street;
}
publicvoidsetCountry(Stringcountry){
this.country=country;
}
publicStringgetStreet(){
returnthis.street;
}
publicStringgetCountry(){
returnthis.country;
}
@Override
publicStringtoString(){
returnnewStringBuffer("Street:").append(this.street).append(
"Country:").append(this.country).toString();
}
}
1.2 WriteObject.java
A simple class to write/serialize the Address object into a file – “c:\\address.ser”.
importjava.io.FileOutputStream;
importjava.io.ObjectOutputStream;
publicclassWriteObject{
publicstaticvoidmain(Stringargs[]){
Addressaddress=newAddress();
address.setStreet("wallstreet");
address.setCountry("unitedstates");
try{
FileOutputStreamfout=newFileOutputStream("c:\\address.ser");
ObjectOutputStreamoos=newObjectOutputStream(fout);
oos.writeObject(address);
oos.close();
System.out.println("Done");
}catch(Exceptionex){
ex.printStackTrace();
}
}
}
1.3 ReadObject.java
A simple class to read/deserialize the Address object from file – “c:\\address.ser”.
importjava.io.FileInputStream;
importjava.io.ObjectInputStream;
publicclassReadObject{
publicstaticvoidmain(Stringargs[]){
Addressaddress;
try{
FileInputStreamfin=newFileInputStream("c:\\address.ser");
ObjectInputStreamois=newObjectInputStream(fin);
address=(Address)ois.readObject();
ois.close();
System.out.println(address);
}catch(Exceptionex){
ex.printStackTrace();
}
}
}
2. Testing
Let do some testing to demonstrate the use of serialVersionUID.
2.1 Same serialVersionUID
Same serialVersionUID , there is no problem during the deserialization process
javacAddress.java
javacWriteObject.java
javacReadObject.java
javaWriteObject
javaReadObject
Street:wallstreetCountry:unitedstates
2.2 Different serialVersionUID
In Address.java,change the serialVersionUID to 2L(it was 1L), and compile it again.
javacAddress.java
javaReadObject
java.io.InvalidClassException:Address;localclassincompatible:
streamclassdescserialVersionUID=1,localclassserialVersionUID=2
...
atReadObject.main(ReadObject.java:14)
The “InvalidClassException
” will raise, because you write a serialization class withserialVersionUID “1L”but try to retrieve it back with updated serialization class,serialVersionUID “2L”.
The serialVersionUID have to match during the serialization and deserialization process.
When should update your serialVersionUID?
When your serialization class is updated with some incompatible Java type changes to a serializable class, you have to update your serialVersionUID.
For detail about the compatible and incompatible Java type changes to a serializable class, see theJava Object Serialization Specification.
3. 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 algorithmhere.
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.
3.1 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.
3.2 File/Database environment
– App #1 is using SUN’s JVM in Windows.
– App #2 is using JRockit in Linux.
Serialization has allowed to save 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.
You can check here for theList of the JVM implementation.
4. How to generate serialVersionUID
You can use JDK “serialver
” or Eclipse IDE to generate serialVersionUID automatically,see detail.
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, how serialVersionUID implement version control and why your class need to use serialization. Understand the serialVersionUID concept is better than blindfold to any recommendation.
References
http://en.wikipedia.org/wiki/List_of_JVM_implementations
http://java.sun.com/javase/6/docs/platform/serialization/spec/class.html#4100
http://stackoverflow.com/questions/419796/explicit-serialversionuid-considered-harmful
http://en.wikipedia.org/wiki/Serialization#Java
http://www.javaworld.com/javaworld/jw-02-2006/jw-0227-control.html?page=1
http://www.javablogging.com/what-is-serialversionuid/
http://java.dzone.com/articles/dont-ignore-serialversionuid
http://www.java-forums.org/new-java/8196-serialversionuid.html
Similar Posts:
- Warning: The serializable class * does not declare a static final serialVersionUID
- Private static final long serialVersionUID = 1L is used to indicate the compatibility between different versions of the class
- Failed to deserialize — local class incompatible: stream classdesc serialVersionUID [Solved]
- ‘required string parameter ‘in springboot ×××’ Is not present solution
- Spring boot project integration redisson throw exception NoClassDefFoundError: lorg / nustaq / serialization / fstconfiguration
- Call to a member function row_array()(function_name) on boolean(type)
- RTNETLINK answers: no such process
- Could not find the file ‘\\\\\\\\\\\\\\\
- org.apache.thrift.TApplicationException: Required field ‘client_protocol’ is unset!
- scp:not a regular file