A hole in the serialization spec
David M. Lloyd
david.lloyd at redhat.com
Mon Feb 10 15:37:00 UTC 2014
I agree that it's a problem; however it's also clear that there are many
classes in the wild which have this problem. It would be nice if the
behavior could _become_ defined *somehow* though. I can see at least
1) do nothing :(
2) start throwing (or writing) an exception in write/readObject when
stream ops are performed without reading fields (maybe can be disabled
with a sys prop or something)
3) leave fields cleared and risk protocol issues
4) silently start reading/writing empty field information (risks
Maybe there are better options I'm not thinking of.
On 02/10/2014 08:53 AM, Chris Hegarty wrote:
> " ... undefined in cases where the ObjectInputStream cannot resolve the
> class which defined the writeObject method in question."
> I'm not clear as to what this statement is about?
> I'm sure you already know this, and maybe in your environment do not
> care much about it, but having a read/writeObject not invoke the
> appropriate default read/write Object/Fields method is a serious
> impediment to evolving the serial form ( in a compatible way ). For
> example, if your class has no serializable fields in one revision, but
> adds a serializable field(s) in a subsequent revision. This could lead
> to a StreamCorruptedException, or some other undefined behavior.
> The OpenJDK sources do seem to be quite tolerant of this situation. I'm
> not entirely sure if this is a good or a bad thing. That said, I don't
> think we want to encourage this kind of behavior.
> On 07/02/14 15:07, David M. Lloyd wrote:
>> Since the topic of serialization has come up recently, I'll take it as
>> an excuse to bring up a problem that I've run into a couple of times
>> with the serialization specification, which has resulted in user
>> If you read section 2.3  of the specification, it says:
>> "The class's writeObject method, if implemented, is responsible for
>> saving the state of the class. Either ObjectOutputStream's
>> defaultWriteObject or writeFields method must be called once (and only
>> once) before writing any optional data that will be needed by the
>> corresponding readObject method to restore the state of the object; even
>> if no optional data is written, defaultWriteObject or writeFields must
>> still be invoked once. If defaultWriteObject or writeFields is not
>> invoked once prior to the writing of optional data (if any), then the
>> behavior of instance deserialization is undefined in cases where the
>> ObjectInputStream cannot resolve the class which defined the writeObject
>> method in question."
>> If you go to section 3.4  of the specification, it reads:
>> "The readObject method of the class, if implemented, is responsible for
>> restoring the state of the class. The values of every field of the
>> object whether transient or not, static or not are set to the default
>> value for the fields type. Either ObjectInputStream's defaultReadObject
>> or readFields method must be called once (and only once) before reading
>> any optional data written by the corresponding writeObject method; even
>> if no optional data is read, defaultReadObject or readFields must still
>> be invoked once."
>> Now the problem: there are many classes in the wild which nevertheless
>> do not write/read fields. We cause an exception in such cases rather
>> than make up some undefined behavior. What I'm wondering is, is there
>> some sensible behavior that could be specified for this case? The
>> Oracle JDK seems to simply leave fields uninitialized in this case,
>> maybe that can be a specified behavior?
More information about the core-libs-dev