A hole in the serialization spec

Chris Hegarty chris.hegarty at oracle.com
Wed Feb 12 15:08:12 UTC 2014


David, others?

I'm afraid I'm still not clear what is mean by:
   " ... undefined in cases where the ObjectInputStream cannot resolve
     the class which defined the writeObject method in question."

This does not seem directly related to the issue we are discussing ( 
whether to invoke default read/write object ).

-Chris.

On 10/02/14 15:37, David M. Lloyd wrote:
> 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
> four options:
>
> 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
> protocol issues)
>
> Maybe there are better options I'm not thinking of.
>
> On 02/10/2014 08:53 AM, Chris Hegarty wrote:
>> David,
>>
>> " ... 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.
>>
>> -Chris.
>>
>> 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
>>> problems.
>>>
>>> If you read section 2.3 [1] 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 [2] 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?
>>>
>>> [1]
>>> http://docs.oracle.com/javase/7/docs/platform/serialization/spec/output.html#861
>>>
>>>
>>>
>>> [2]
>>> http://docs.oracle.com/javase/7/docs/platform/serialization/spec/input.html#2971
>>>
>>>
>>>
>>>
>
>



More information about the core-libs-dev mailing list