views:

647

answers:

5

I am probably risking some downvotes on this.

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?

+7  A: 

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.

Jon Skeet
Makes sense, thanks.
Hemal Pandya
+2  A: 

When you need to support long-time persistence via serialization, then you almost always need to use custom code to support this and need to explicitly set the serialVersionUID, as otherwise older serialized version will not be de-serializable by newer code.

Those scenarios already require a great deal of care in order to get all the cases correct, when the class changes, so the serialVersionUID is the least of your problems.

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, as the computed value will make sure that the correct version is used.

Joachim Sauer
Like you said, to provide long-term deserializability a lot has to be done, probably version special deserialization routines etc. Thanks for your response.
Hemal Pandya
+1  A: 

Whether you go for serialVersionUID or not (I suggest you do), then you should really consider creating a comprehensive set of tests for serial compatibility.

It's also worth designing the serial format with care. It is effectively a public API.

Tom Hawtin - tackline
Thanks. For any serious serializing I suspect Java serialization would not be used. For database persistence for example, there usually is an upgrade script and extensive testing.
Hemal Pandya
+5  A: 

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.

Yoni Roit
It's annoying and misleading that Eclipse defaults to warning that there's no serialVersionUID
Steve Kuo
This used to be my point of view as well, until about a month ago when I was educated about the issue pointed out by Jon Skeet. This puts other restrictions on your runtime to guarantee serialization works properly.
Robin
Robin: I guess it's a matter of priorities. We're much more scared of strange bugs than switching compilers for debugging.
Yoni Roit
+2  A: 

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.

james