EnumSet.class serialization broken - twice

Peter Levart peter.levart at gmail.com
Tue Jun 18 14:32:03 UTC 2019



On 6/18/19 4:00 PM, Martin Buchholz wrote:
> Java Historian says:
> I was a reviewer for Effective Java 3rd Edition and EnumSet is the 
> canonical example of the Serialization Proxy pattern,
> so I tried to make sure the pattern was implemented as perfectly as 
> possible.
> 8192935: Fix EnumSet's SerializationProxy javadoc
> All of us who try to make java serialization work right have a mental 
> model of the many things that might go wrong.
> Serialization of Class objects has never been part of my own mental 
> model - I've only ever considered instances.

Perhaps the necessity for Class objects representing Serializable 
classes to agree in sertialVersionUID is a bug in Java serialization 
implementation? There's no such requirement for Class objects 
representing non-Serializable classes and I don't see why this 
requirement is there for Serializable classes. Could this requirement 
simply be relaxed with no ill consequences?

Regards, Peter

>
>
> On Tue, Jun 18, 2019 at 5:32 AM Peter Levart <peter.levart at gmail.com 
> <mailto:peter.levart at gmail.com>> wrote:
>
>     Hi,
>
>     I recently stumbled on an exception thrown when deserializing stream
>     produced on JDK 8 and read with JDK 11. I narrowed the problem
>     down to
>     serialization/deserialization of a public EnumSet.class object. There
>     were several changes made to EnumSet in the Mercurial history of jdk
>     repo, but I think the following two broke the serialization:
>
>     http://hg.openjdk.java.net/jdk/jdk/rev/d0e8542ef650
>     http://hg.openjdk.java.net/jdk/jdk/rev/a7e13065a7a0
>
>     It is interesting to note that before those two changes were made,
>     there
>     was a chance to fix the problem reported by newly added serial lint
>     warnings. Unfortunately they were just silenced:
>
>     http://hg.openjdk.java.net/jdk/jdk/rev/501d8479f798
>
>     + at SuppressWarnings("serial") // No serialVersionUID due to usage of
>     +                            // serial proxy pattern
>
>     It is true that serialization of instances of Serializable classes is
>     not broken by changes to them when they implement serial proxy
>     pattern
>     (i.e. writeReplace() method) even if they don't itself declare a
>     private
>     static final long serialVersionUID field, but this is not true of
>     Class
>     objects representing those Serializable classes. It is even more
>     controversial that serialization of Class objects representing
>     non-Serializable classes is never broken (which is understandable as
>     they don't have a habit of declaring serialVersionUID fields).
>
>     Both of the above braking changes were made post JDK 8 release, so
>     deserialization of JDK 8 (and older) streams is affected in all
>     JDK 9 +
>     releases or vice versa.
>
>     So, what shall be done. I suggest adding serialVersionUID field to
>     EnumSet vith a value that corresponds to JDK 8 serialization
>     format and
>     later backport this change to JDK 11.
>
>     What do you think?
>
>
>     Regards, Peter
>
>
>     PS: ImmutableCollections nested classes also implement serial proxy
>     pattern and don't declare serialVersionUID fields, but they are not
>     public, so it is less chance that Class objects representing them
>     could
>     be used in serial streams, although it is not impossible. For example:
>
>     objectOutputStream.writeObject(Set.of().getClass());
>



More information about the core-libs-dev mailing list