JDK 9 RFR of JDK-8035452: Fix serial lint warnings in core libs
Joe Darcy
joe.darcy at oracle.com
Tue Mar 4 06:05:51 UTC 2014
Hi Stuart,
Thanks for the careful review. I agree the case of
TreeMap.NavigableSbugMap requires some more investigation. In the
meantime, I'd like to proceed with the revised patch below for EnumSet
and ExceptionProxy.
Thanks,
-Joe
diff -r 6cfedc362f48 src/share/classes/java/util/EnumSet.java
--- a/src/share/classes/java/util/EnumSet.java Mon Mar 03 18:17:00
2014 +0400
+++ b/src/share/classes/java/util/EnumSet.java Mon Mar 03 22:02:06
2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights
reserved.
+ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights
reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -77,6 +77,8 @@
* @see EnumMap
* @serial exclude
*/
+ at SuppressWarnings("serial") // No serialVersionUID due to usage of
+ // serial proxy pattern
public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E>
implements Cloneable, java.io.Serializable
{
diff -r 6cfedc362f48
src/share/classes/sun/reflect/annotation/ExceptionProxy.java
--- a/src/share/classes/sun/reflect/annotation/ExceptionProxy.java Mon
Mar 03 18:17:00 2014 +0400
+++ b/src/share/classes/sun/reflect/annotation/ExceptionProxy.java Mon
Mar 03 22:02:06 2014 -0800
@@ -37,5 +37,6 @@
* @since 1.5
*/
public abstract class ExceptionProxy implements java.io.Serializable {
+ private static final long serialVersionUID = 7241930048386631401L;
protected abstract RuntimeException generateException();
}
On 02/28/2014 08:58 AM, Stuart Marks wrote:
> On 2/27/14 12:11 PM, Joe Darcy wrote:
>> I am trying hard to remain blissfully ignorant of any more low-level
>> details of
>> the serialization format; however, I might not be successful on that
>> goal much
>> longer ;-)
>
> I believe your latter statement is correct. :-)
>
>> My preference in a case like this is to add the svuid if for no other
>> reason
>> that is is simple to explain and understand, even if it is not
>> strictly required.
>
> In general, it does seem reasonable to add a svuid in cases where it's
> difficult or impractical to prove that the lack of a svuid causes no
> compatibility issues.
>
>> There is a difference in character between a serializable class in
>> Java SE
>> (java.* and javax.*) and the jdk.Exported(true) types in the JDK and a
>> serializable class that lives in sun.* or some other
>> jdk.Exported(false) area.
>>
>> For that latter, the serialization contract has to be different, with
>> fewer
>> guarantees, just as the general usage contract for those types has fewer
>> guarantees. I think this is analogous to putting non-serializable
>> classes into
>> collections; the collection itself is serializable, but it won't be
>> anymore if
>> you put non-serializable objects into it.
>>
>> If a user happens to have a direct or indirect reference to an object
>> of a JDK
>> implementation type, the compatibility contract is weaker than if an
>> object with
>> a public Java SE type were being dealt with.
>
> I'm not sure I buy this. Unfortunately, serialization differs from the
> general usage contract in that serialization exposes internals. Just
> like it can expose private (non-transient) fields, serialization can
> also can expose what might otherwise look like purely internal
> implementation types.
>
> The canonical example of how an application can get a reference to an
> apparently internal class is java.util.TimeZone. If an app calls
> TimeZone.getDefault(), it gets back an instance of
> sun.util.calendar.ZoneInfo without ever mentioning this class by name.
> Furthermore, TimeZone and ZoneInfo are serializable, so they can be
> serialized directly or as part of another serializable object graph,
> and an instance of s.u.c.ZoneInfo does appear in the serialized byte
> stream. If s.u.c.ZoneInfo were not to have a svuid, an apparently
> innocuous change to it would clearly cause application incompatibilities.
>
> As it happens, s.u.c.ZoneInfo does have a svuid. I also note in
> passing that TimeZone, an abstract class, also has a svuid.
>
>>> Finally, EnumSet doesn't need a serial version UID. It's serialized
>>> using a
>>> proxy class, so EnumSet never appears in a serialized byte stream.
>>> (Note, its
>>> readObject throws an exception unconditionally.) So it's probably
>>> safe to
>>> suppress its serialization warning.
>>
>> Yes, EnumSet was a bit tricky, it is serializable itself, but uses a
>> proxy
>> internally. ("Effective Java, 2nd edition" both recommends the proxy
>> pattern and
>> recommends adding a svuid to all serializable classes, but doesn't
>> explicitly
>> give guidance to this combination of features.)
>>
>> To avoid adding a long comment explaining the proxy pattern and why a
>> svuid on
>> EnumSet isn't really required, my preference would just be to add the
>> svuid if
>> it doesn't cause any harm.
>
> In this case I think it's possible by local reasoning (looking
> elsewhere in the EnumSet.java source code) to determine that EnumSet
> instances themselves are never actually serialized, because of the use
> of the serialization proxy pattern. If nothing else, adding a svuid
> here sets a bad example, so suppressing the warning is reasonable. I
> don't think a long comment is necessary. Probably something like the
> following is sufficient:
>
> @SuppressWarnings("serial") // no serialVersionUID because of
> serialization proxy
>
> s'marks
>
>
>
>
More information about the core-libs-dev
mailing list