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

Chris Hegarty chris.hegarty at oracle.com
Thu Mar 19 15:49:16 UTC 2015


On 19/03/15 15:21, Peter Levart wrote:
> On 03/19/2015 11:35 AM, Peter Firmstone wrote:
>> Chris / Peter,
>>
>> Perhaps you could consider passing GetFields as a parameter to a
>> static method (identified by an annotation) and use fieldSetter to
>> change the fields before they're written?

Interesting idea. I'm reluctant to add confusion by mixing the concept 
of stream field values and object fields values, so I think the 
FieldSetter and GetField APIs should remain independent.

> Or change the fields *as* they are written. It actually doesn't matter
> if the method is static.
>
>>
>> That way it would be possible to not only avoid implementing
>> readObject or writeObject, but to check invariants and be final field
>> friendly.
>>
>> Just a thought.
>>
>> Peter.
>
> So you mean something like this or a variant of it. Instead of
> readObject() instance method, a static method with an additional
> FieldAccess parameter:
>
> @ReadObject
> 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?
> }
>
>
> That's interesting. When operating with FieldSetter API or when calling
> ObjectInputStream methods, one actually doesn't need an instance
> context, since it is hidden behind the ObjectInputStream/FieldAccess
> objects, so the @ReadObject method could be static, which would prevent
> undesirable direct access to fields (finals in particular).

If this is primarily about checking invariants of stream field values, I 
am working through a proposal for a static validator method and better 
failure atomicity, and hope to have something to share soon.
Though, I think this is an orthogonal issue. Maybe FieldSetter can help 
here, I'm not sure.

What is being proposed by the FieldSetter is a very simple low-level API 
that addresses a long standing issue. Regardless of other changes to 
Serialization, I think this proposal, as it stands, is good.

> One thing you couldn't do this way is to check the invariants that
> involve superclass' state that has already been deserialized.

This is a difficult problem.

> But if you don't need that, this could be an alrernative readObject()
> method. Very easy to implement, actually.

-Chris.

>
>
> Regards, Peter
>
>>
>>
>>> ------------------------------
>>>
>>> Message: 5
>>> Date: Wed, 18 Mar 2015 11:06:56 +0000
>>> From: Chris Hegarty<chris.hegarty at oracle.com>
>>> To: Alan Bateman<Alan.Bateman at oracle.com>,    Peter Levart
>>>     <peter.levart at gmail.com>
>>> Cc: Core-Libs-Dev Libs<core-libs-dev at openjdk.java.net>
>>> Subject: Re: RFR [9] 8071472: Add field access to support setting
>>>     final fields    in readObject
>>> Message-ID:<55095C50.3010605 at oracle.com>
>>> Content-Type: text/plain; charset=windows-1252; format=flowed
>>>
>>> On 17/03/15 13:42, Alan Bateman wrote:
>>>> On 17/03/2015 12:21, Peter Levart wrote:
>>>>> Hi Alan,
>>>>>
>>>>> I agree that not calling defaultReadObject() from readObject() and
>>>>> having a final field is potentially a bug. But need not be in case
>>>>> some other means of setting final fields was used (Unsafe or
>>>>> reflection). Some readObject() implementations in base module that
>>>>> Chris changed to use new API fall into this category. We can't track
>>>>> those usages, so to keep backwards compatibility, this checking has to
>>>>> be opt-in. Is there a more elegant way to opt-in? A
>>>>> @CheckFinalsAssignment annotation on the readObject() method?
>>>> I'm not sure that an annotation is right here. Instead then it might
>>>> work as a method on FieldSetter to enable strict checking.
>>> Peter suggested a method on FieldSetter to enable strict checking before
>>> too, and at the time I pushed back. After this discussion, I've come
>>> full circle, and maybe this opt-in style method is a reasonable
>>> compromise. Something like:
>>>
>>>    /**
>>>     * Checks that all final instance fields, declared by the class where
>>>     * the {@code readObject} callback is being invoked, have been set.
>>>     *
>>>     *<p>  This method is intended to be called as a final step after all
>>>     * final instance fields have been set.
>>>     *
>>>     * @throws InvalidObjectException if one, or more, final instance
>>>     *         fields have not been set
>>>     */
>>>    void checkAllFinalsSet() throws InvalidObjectException;
>>>
>>>
>>> ...and the user code would look similar to this, from java.io.File:
>>>
>>>     s.fieldSetter().set("path", p)
>>>                    .set("prefixLength", pLen)
>>>                    .checkAllFinalsSet();
>>>
>>> -Chris.
>>>
>>>
>>>
>>>
>>> End of core-libs-dev Digest, Vol 95, Issue 54
>>> *********************************************
>>
>



More information about the core-libs-dev mailing list