Hi Martin,
Yes, um, I agree. :-) Perhaps theere is some hope here:
http://openjdk.java.net/jeps/187
Which of course will avoid all the mistakes in the first version of
serialization. That will create room for bigger and better mistakes. :-)
And then of course there is this:
http://openjdk.java.net/jeps/154
s'marks
On 2/25/14 10:33 AM, Martin Buchholz wrote:
(As I've said before ...)
Serialization is too hard to get right. You need a full-time engineer (Peter
Jones used to be that) who specializes in serialization and builds tools to
ensure that serialization is implemented correctly, e.g. that internal
implementation details don't leak out and that cross-version and
cross-implementation tests are written so that the promise of serialization is
not broken by careless JDK engineers (no one is careful enough!). Our testing
culture and tools tend to assume only a single JDK at a time.
The default serialization tries to be helpful, but too often exposes
implementation details. It would have been better to force everyone to write
those writeObject methods. It would have been better if most Collection
implementations serialized the same way, an int size followed by all the
elements in iterator order. There should have been a utility method to help
do that. Compare and contrast with the reliable "serialization" provided by
Collection.toString.
On Mon, Feb 24, 2014 at 10:53 PM, Stuart Marks <stuart.ma...@oracle.com
<mailto:stuart.ma...@oracle.com>> wrote:
On 2/24/14 8:22 PM, Joe Darcy wrote:
On 02/20/2014 12:49 PM, Paul Benedict wrote:
Joe, I find it interesting that you suppressed the serial warning
on an
abstract class. I'd like to know more about that. Is this a
universal rule?
Are serial uids not important for abstract classes?
I wouldn't generalize that way from this example.
The serial hash of NavigableSubMap has differed in different JDK
releases,
but its subclasses do define serialVersionUID fields. I assume the set
of
non-transient fields in NavigableSubMap has stayed unchanged, but I
haven't
verified that.
If I hadn't found the change in the hash value, I would have added the
serialVersionUID to NavigableSubMap too.
And in his reply to Paul, Joe said:
From what I was able to discern by reading the serialization
specification
[1], If a class does *not* declare a serialVersionUID, the
serialVersionUID
of its superclass is *not* included in the serialver hash computation
of the
child class. However, my understanding is that changes to the fields
stored
in superclass and changes to the semantics of its readObject /
writeObjects
methods could affect the serialization of the child class.
I think we need to take a closer look at these issues.
I believe that abstract, serializable superclasses *do* need to have a
serialVersionUID defined. The reason is that when a subclass is
serialized, its superclass descriptor (an ObjectStreamClass) is also
serialized. Upon deserialization, the descriptor's svuid is matched
against the svuid of the class loaded at runtime, and if there is a
mismatch, InvalidClassException ensues.
While the svuid of an abstract superclass isn't included in the subclass'
svuid hash, the svuid of the superclass does affect serial compatibility
of subclasses as described above. Thus, an apparently innocuous change to
the superclass might prevent serial compatibility of its subclasses, no
matter how carefully the subclasses are programmed.
If the NavigableSubMap class has changed svuid values over several
releases, well, unfortunately we may have a compatibility problem already
in the field. We'd need to choose which release to be compatible with.
Since 8 isn't quite out yet, we might be able to change an early 8-update
and 9 to be compatibile with the latest 7-update.
Note that the svuid of a class does not relate solely to the fields that
are serialized. It's an attempt at a version hash of the *implementation*
of a class, not a version of the serial protocol. Even changes to a class
that don't affect the serialized output stream can affect the svuid. For
example, renaming a package-private method will affect the svuid. See
section 4.6 of the serialization spec.
While we're at it (sorry...) in the diffs for your other serial warnings
patch JDK-8035453, there are several lines where the serial warning is
suppressed like so:
+@SuppressWarnings("serial") // JDK implementation class
As you know, serialization can expose the private fields of a class,
making them public in a sense. Serialization can also expose what are
internal, implementation classes, if these classes are part of a
serializable object graph that is exposed to applications. I don't know
about the specific situation with the DOM classes, but even if a
serializable class is internal, we might need to be concerned about
serialization compatibility.
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.
s'marks