Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

explicit serialVersionUID considered harmful?

It seems to me that explicitly specifying serialVersionUID for new classes is bad. Consider the two cases of not changing it when layout has it should have been changed and changing it when it should not have.

Not changing when it should have been changed occurs almost only when it is explicit. In this case, it results in some very subtle, hard-to-find bugs. Especially during development, when class layout changes often. But if it has not been explicitly specified, it will change and the deserialization will break loudly, mostly likely solved by purging the repository.

Changing it when should not have would occur almost only when it is implicit. This is the rare case where class layout has changed but we still want to deserialize from the old serialized blobs. This will likely be caught during QA (Strange errors after upgrade from 5.2 to 5.2.1, see attached stack trace) and can be trivially fixed by setting a explicit value.

Comments?

like image 973
Miserable Variable Avatar asked Jan 07 '09 10:01

Miserable Variable


People also ask

What does serialVersionUID mean?

The SerialVersionUID can be used during deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible w.r.t serialization. If the deserialization object is different than serialization, then it can throw an InvalidClassException.

What is a serialVersionUID and why should I use it?

SerialVersionUID is a unique identifier for each class, JVM uses it to compare the versions of the class ensuring that the same class was used during Serialization is loaded during Deserialization. Specifying one gives more control, though JVM does generate one if you don't specify.

Should I set serialVersionUID?

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, and can thus result in unexpected InvalidClassExceptions during ...

How do you declare serialVersionUID?

A serializable class can declare its own serialVersionUID explicitly by declaring a field named “ serialVersionUID ” that must be static, final, and of type long.


3 Answers

Changing when it shouldn't may happen for reasons other than class layout changes - the problem is that it's compiler implementation dependent. If you do debug with Eclipse but do production builds with javac, you may end up with two incompatible sets of data.

like image 63
Jon Skeet Avatar answered Oct 20 '22 10:10

Jon Skeet


At my work we explicitly prohibit specifying serialVersionUID, exactly because of the problems you bring up.

In addition, the classes we persist are only used to store data with no logic inside, so the only way they change is because of changing data members.

like image 41
Yoni Roit Avatar answered Oct 20 '22 09:10

Yoni Roit


to further emphasize what john skeet said and to contradict the comment:

"If you don't need that (i.e. you always serialize and de-serialize with the same class version), then you can safely skip the explicit declaration"

Even if you are not serializing long-term and are using the same class version, you could still have issues. if you are writing client-server code and the client code could run w/ a different jvm version/implementation than the server you can have the same problems with incompatible serialversionuids.

to summarize, the only time it is "safe" to not specify serialversionuids is when you are not serializing long-term and you are guaranteed that all consumers of the serialized data will be using the same jvm implementation and version as the original producer.

in short, not using serialversionuid is generally the more harmful situation.

like image 4
james Avatar answered Oct 20 '22 11:10

james