JDK-8065937 : need way to handle multiple serialVersionUIDs for one class
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.io:serialization
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: generic
  • CPU: generic
  • Submitted: 2014-11-25
  • Updated: 2019-07-16
Related Reports
Relates :  
Description
Every once in awhile we make a mistake.  We create a serializable class, usually an exception
class, without an explicit serialVersionUID.  An update to the class then changes the implicit
serialVersionUID.  It's impossible to create a third version of the class that fixes the bug by
including an explicit serialVersionUID and that handles the serialized data from both of the
previous versions.

It would be nice if the serialization subsystem handled this, e.g, by allowing the class to have an
acceptSerialVersionUID(long uid) method and a long chooseSerialVersionUID() method.
(The reading case is easy; the writing case is harder to know which uid to use.)
Comments
The technique (or "ugly hack") that was discussed relative to the other bug is to set the serialVersionUID in a static initializer block, optionally based on some logic. For example, the svuid value could be set to one value or another based on a system property. This would work in the cases where there are past releases A and B of a system with incompatible svuids. Release C could be run with the system property set one way or another to choose compatibility with either A or B but not both. The limitation is that the svuid must be assigned *once* at class initialization time, and this fixes the compatibility space for this run of the JVM. This doesn't really help the use case of release C trying to be compatible with both releases A and B simultaneously.
16-07-2019

Discussion related to how to address JDK-8227368 in update releases included the approach of setting the serialVesionUID in a static initializer block, or similar ugly hack.
16-07-2019

It's possible to deserialize an object with a different serialVersionUID, but it's quite complicated. 1) You have to have class bytes for a class that has or declares the other serialVersionUID you want to support. 2) You have to subclass ObjectInputStream and override resolveClass() to catch the case where it encounters an ObjectStreamClass that has the other svuid, before it attempts to load that class. 3) You have to load the other class's class bytes into a classloader of your own and return that class from resolveClass(), which deserializes the object using the alternative class. This is quite complicated and error-prone, especially if the class depends on a mixture of ordinary and alternative classes. Bill has stated that the need to override ObjectInputStream makes it unacceptable for his purposes. The checking of the resolved class against the class descriptor from the stream is checked in ObjectStreamClass.initNonProxy(). This checks the class name, and svuid among other things and is fairly deeply hardwired. Any relaxation of these checks would need to be very carefully examined for security implications.
26-11-2014