On 20/01/15 20:22, Peter Levart wrote:
Hi Chris and Peter,

It just occurred to me that the following scheme would provide failure
atomicity for the whole Object regardless of whether readObject methods
are used or not for various classes in hierarchy:


- allocate uninitialized instance
- call default accessible constructor of the most specific
non-Serializable class
- deserialize (by calling readObject methods where provided) the fields
of all classes in hierarchy like normally
(up to this point, nothing is changed from what we have now)
- if deserialization fails anywhere, undo everything by setting all the
fields in the Serializable part of the hierarchy to default values (null
for references, 0 for primitives), abandon the object and propagate failure.

I think this is a good idea, and I can prototype something to this affect.

-Chris.


While deserializing, the object is in inconsistent state. If
deserialization fails, this state is rolled-back to uninitialized state.
finalize() can still get to the instance, but it will be uninitialized.


Peter

On 01/14/2015 01:58 PM, Peter Firmstone wrote:

Hi Chris,

Sorry, no.

Currently when an ObjectStreamClass is read in from the stream, the
framework searches for the first zero arg constructor of a non
serializable class and creates and instance of the class read and
resolved from the stream, however it does so using a super class
constructor.

Then from the super class down, fields are read in and set in order
for each class in the object's inheritance hierarchy.

The alternative I propose, doesn't create the instance, instead it
reads the fields from the stream, one by one and without instantiating
them, if they are newly read objects, stores them temporarily into
byte [] arrays in a Map with reference handle keys, otherwise it just
holds the reference handle.

What it does next is wrap this information into a caller sensitive
api, GetFields or ReadSerial instance, that is passed as a constructor
parameter to the child class serial constructor.

The child class checks invariants and reads each field it needs using
a static method prior to calling a superclass constructor, each class
in the inheritance hierarchy for the object then checks its invariants
until it gets to the first non serializable superclass.

The benefit of this order is that each class is present in the thread
security context, so protection domain security and invariants are
enforced before instantiating an object.

Hope this helps illuminate it a little better, regards,

Peter.

----- Original message -----
> Peter F,
>
> I am still struggling with the basic concept of you proposal. Let me
see
> if I understand it correctly. Does the following describe a similar
> scenario as you envisage:
>
>    1) For each Serializable type, T, in the deserialized types
>          hierarchy, starting with the top most ( closest to
j.l.Object ),
>
>          1a) Read T's fields from the stream, fields
>
>          1b) validate(t, fields)  // t will be null first time
>
>          1c) allocate a new instance of T, and assign to t
>
>          1d) set fields in t
>
>    2) Return t;
>
> So for each level in the hierarchy, an instance of a type is created
> only after its invariants have been checked. This instance is then
> passed to the next level so it can participate in that levels
invariants
> validation.
>
> If this scenario is along the same lines as yours, then I just don't
see
> how 1c above will always be possible.
>
> If we could somehow make the object caller sensitive until after
> deserialization completes, then could avoid having to try to allocate
> multiple instance down the hierarchy.
>
> -Chris.
>
> On 13/01/15 10:24, Peter Firmstone wrote:
> > Could we use a static validator method and generate bytecode for
> > constructors dynamically?
> >
> > The developer can optionally implement the constructors.
> >
> > static GetField invariantCheck(GetField f);
> >
> > Create a caller sensitive GetField implementation and add a two new
> > methods to GetField:
> >
> > abstract Object createSuper(); // to access superclass object methods
> > for inavariant checking.
> >
> > abstract Class getType(String name);
> >
> > Set fields from within constructors.
> >
> > The generated constructors are straight forward:
> >
> > 1. Call static method.
> > 2. Call super class constructor with result from static method.
> > 3. Set final fields
> > 4. How to set transient fields, implement a private method called
from
> > within the constructor?
> >
> > Require a permission to extend GetField?
> >


Reply via email to