Fw: Re: RFR [9] 8071472: Add field access to support, setting final fields in readObject

Peter Firmstone peter.firmstone at zeus.net.au
Sun Mar 22 05:53:54 UTC 2015


Was there a use you had in mind, or some other reason you thought the spec should be modified to accomodate it?

Such as improve serial form evolution flexibility, when someone's forgotten to call defaultReadObject|WriteObject?

I'm not sure how that can be implemented though, requires further thought; to see if it can be done without breaking the serialization stream protocol.

Regards,

Peter.

----- Original message -----
> What happens, to answer your question, is the fields, if any, won't
> appear in the stream where they are supposed to be.
> 
> Again this will affect evolvability of serial form.   In other words,
> incorrect implementations are locked into their current serial form.   I
> don't think that's something that should be encouraged.
> 
> ----- Original message -----
> > If an object defines readObject(), then it is responsible for reading
> > fields.
> > 
> > So lets say for arguments sake that all fields are transient in the
> > first version of an Object and it doesn't call defaultReadObject or
> > GetFields before reading in block data.
> > 
> > If at some later time the developer defines a non-transient field, the
> > earlier version cannot deserialise the later versions serial form,
> > because the field appears in the stream, when it is expecting block
> > data.
> > 
> > If the developer decided instead to call defaultReadObject even if all
> > fields were transient, then backward compatibility is preserved because
> > the fields are removed from the stream, before the earlier object
> > version reads block data following the fields.
> > 
> > Now lets say, for the sake of another example, that an object writes
> > block data, before writing fields.
> > 
> > Food for thought:
> > 
> > How is excess block data or an additional field discarded by the stream
> > by earlier versions if an Object's later version adds fields or block
> > data?
> > 
> > Regards,
> > 
> > Peter.
> > 
> > 
> > ----- Original message -----
> > > I think you didn't understand the issue being discussed - it's not
> > > about    fields that are added/removed, which is very clearly defined
> > > in the    spec.     It's about what happens when you don't call 
> > > defaultRead|WriteFields, which is required by spec but not always
> > > done   in practice.
> > > 
> > > On 03/20/2015 10:05 PM, Peter Firmstone wrote:
> > > > The reason for this part of the spec, is backward compatible
> > > > evolvability of serial form.
> > > > 
> > > > It allows an earlier implementation of a class to deserialize
> > > > serial form from a later implementation that includes additional
> > > > fields or values written to the stream, and allow them to be
> > > > discarded by ObjectInputStream, when the earilier implementation
> > > > doesn't read/consume them.
> > > > 
> > > > If classes deliberately break the contract / spec, then although
> > > > they function, they limit their backward compatible evolvability;
> > > > in other words, if a later class has additional fields or writes
> > > > additional values to the stream, a StreamCorruptedException will
> > > > occur when an earlier class implementation reads it.
> > > > 
> > > > For that reason, I'd reccommend against including it in the spec.
> > > > 
> > > > Regards,
> > > > 
> > > > Peter.
> > > > 
> > > > 
> > > > > ------------------------------
> > > > > 
> > > > > Message: 4
> > > > > Date: Fri, 20 Mar 2015 11:57:04 -0500
> > > > > From: "David M. Lloyd"<david.lloyd at redhat.com>
> > > > > To: core-libs-dev at openjdk.java.net
> > > > > Subject: Re: Fw: Re: RFR [9] 8071472: Add field access to support
> > > > > setting         final fields in readObject
> > > > > Message-ID:<550C5160.2030106 at redhat.com>
> > > > > Content-Type: text/plain; charset=utf-8; format=flowed
> > > > > 
> > > > > On 03/20/2015 09:31 AM, Peter Levart wrote:
> > > > > > On 03/20/2015 02:03 PM, David M. Lloyd wrote:
> > > > > > > > > private static void altReadObject(ObjectInputStream in,
> > > > > > > > > FieldAccess fieldAccess) throws IOException,
> > > > > > > > > ClassNotFoundException { // the same as in readObject,
> > > > > > > > > but doesn't have direct access to
> > > > > > > > > instance state, so everything must go through FieldAccess
> > > > > > > > > API? }
> > > > > > > > > 
> > > > > > > > > 
> > > > > > > > Yes.
> > > > > > > An interesting aspect of this approach is that it deals with
> > > > > > > a problem in the serialization spec [1] where it specifically
> > > > > > > says that serializable classes should be reading/writing
> > > > > > > stream fields always, and before reading/writing other data:
> > > > > > > 
> > > > > > > In section 3.4: "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."
> > > > > > > 
> > > > > > > In section 2.3: "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."
> > > > > > > 
> > > > > > > But classes (even JDK classes) often disregard this
> > > > > > > requirement, relying on known implementation behavior and
> > > > > > > either reading/writing optional data before fields or just
> > > > > > > not reading/writing fields at all.     So either the spec
> > > > > > > should be updated (I've tried to do this but nobody seems to
> > > > > > > know how to modify this old content I guess) to match
> > > > > > > behavior, or the spec should be enforced more strictly -
> > > > > > > however doing the latter *will* break a lot of user code,
> > > > > > > *unless* an alternative readObject method is introduced with
> > > > > > > the more strict enforcement.     But I guess even in this
> > > > > > > case, the spec should be updated to allow the implementation
> > > > > > > behavior.
> > > > > > > 
> > > > > > > [1]
> > > > > > > http://docs.oracle.com/javase/8/docs/platform/serialization/spec/serialTOC.html
> > > > > > > 
> > > > > > > 
> > > > > > I guess this would need an alternative writeObject method too,
> > > > > > with more strict enforcement, or not?
> > > > > Sounds fine to me...
> > > > > 
> > > > > > I don't know from the top of my head, but does the order of
> > > > > > writing optional data (before or after) fields, change the
> > > > > > order of data emitted in stream and does that order have to be
> > > > > > respected when reading back in readObject()?
> > > > > Yes.
> > > > > 
> > > > > > In that case, I guess, we would need an alternative
> > > > > > writeObject method too, with more strict enforcement of order.
> > > > > > But I think that having two different rules for old
> > > > > > read/writeObject and alternative read/writeObject would just
> > > > > > confuse people. If current rules don't present any problem
> > > > > > (apart from being looser then specification requires) then
> > > > > > perhaps just specification should be updated.
> > > > > Maybe.
> > > > > 
> > > > 
> > > 
> > > -- 
> > > - DML
> > 
> 




More information about the core-libs-dev mailing list