SerialVersionUID in the standard Java library for different JVMs

Based on the description of SerialVersionUID here: https://docs.oracle.com/javase/8/docs/platform/serialization/spec/class.html#a4100 , it seems necessary to always include SerialVersionUID in any classes that you create so that the JVM used for serialization, and the other JVM used for deserialization does not automatically assign its own SerialVersionUID, which may differ from each other due to differences in the JVM. This works well for controlling the deserialization of my own classes, but what if I want the classes in the standard library serialized with JVM A to be deserialized with JVM B?

Map<Integer, String> myMap = new HashMap<>(); 

HashMap defines a SerialVersionUID. But:

  • Since the HashMap lives in the java standard library, do I provide any guarantee that if I serialize this HashMap with JVM A, that JVM B can deserialize it? Namely, is JVM B allowed to specify a different SerialVersionUID than JVM A, at least if B is just a small version update from A?
  • If this is not guaranteed for standard library classes, does SerialVersionUID only use true deserialization for your own classes that never touch the standard java library? For example, a class that looks like this:

     public class NewClass implements Serializable { private static final long serialVersionUID = 1L; private final Map<Integer, String> myMap; public NewClass() { this.myMap = new HashMap<>(); } } 

    will be error prone since deserialization depends on the fact that the HashMap has the same SerialVersionUID that may be different in different JVMs, right?

+7
java serialization serialversionuid
source share
1 answer

Potentially yes, you are right.

In fact, this happened to us some time ago with some swing classes (I really donโ€™t remember what exactly), but it is serialized on jdkX and de-serailizng them on jdkX+1 (it was a very long time ago, sorry for the lack of these details) things started to burst with an InvalidClassException . At that time, we paid support and discovered the problem - the answer was, well, that these classes changed in such a way that it would be impossible to deserialize them correctly - you are stuck with this version or jdk+1 to jdk+1 and use this. Since then, this has not happened to me, not even once.

All in all, I think that makes serialization too complicated. You must support this process so that changes in future versions can be relevant and compatible with previous ones in terms of serialization.

HashMap , on the other hand, has a very smart way to serialize data. It serializes (by the way, likes load_factor , etc.). Only its keys and values โ€‹โ€‹are nothing more. Therefore, regardless of whether the implementation is changed, it will be possible to de-serialize. For this reason, some of the fields that are not needed are marked as transient, for example:

  transient int modCount; transient Set<Map.Entry<K,V>> entrySet; 

The idea is that it should serialize the data compared to the structure.


If the HashMap changes in such a way that Serialization will break into jdk-11 , for example, it will make many developers pissed off, I doubt it will ever be traversed (if it is really necessary)

+1
source share

All Articles