Description
Currently, some serializable classes in the standard library have a @SerialVersionUID
annotation, others don't. The process is ad-hoc.
If a class does not have an SVUID, it is computed by the VM. The computed value is sensitive to changes in the classfile that don't affect deserialization, for example adding a public method. So in general, serializable classes should have an SVUID to prevent InvalidClassException
s on binary compatible changes (like adding an overriding method to a class).
On the other hand, there are no checks in place to identify serialization-incompatible changes. It is not even clear what kind of change should be considered serialization incompatible: adding or removing fields will never cause deserialization to fail, the field will just carry the zero value / the serialized value will be discarded. This can lead to errors, example here: scala/scala#5429 (comment).
We should have an -Xlint
warning for subclasses (abstract and concrete, not traits) of Serializable
that don't have the annotation.
One idea by Adriaan is to put an explicit annotation on all serializable classes and update the ID on every major release. He mentions that the checks done by MiMa would ensure serialization compatibility. However, I think binary compatibility is not sufficient: for example, adding or removing a private field is binary compatible, but not serialization compatible. We could probably extend MiMa to also perform serialization compatibility checking.
Side-note: we should use 1L
by default and increase in major releases. https://stackoverflow.com/questions/888335/why-generate-long-serialversionuid-instead-of-a-simple-1l