RE: JavaMemoryModel: Re: Serialization and final fields - what happened?

From: David Holmes (dholmes@dltech.com.au)
Date: Thu Mar 03 2005 - 19:45:31 EST


Doug Lea writes:
> >
> > You can set a final field using Field.set if:
> > a) the field is non-static; and
> > b) setAccessible(true) succeeds
> >
>
> It would be great to redo this right.
>
> In most senses, the best solution would be to allow any class to
> reflectively set final fields during deserialization but not
> otherwise.
>
> But among the problems with this is that a lot of code out there does
> some kind of pseudo-deserialization (from database records, XML,
> etc). So you can't tie the rules to deserialization proper. So there
> has to be some more general escape hatch. Probably something tied to
> the current setAccessible rule, but somehow less general.

I think it will be very difficult to re-bolt this stable door now that it
has been opened again. The way I see this initially moving forward is to
allow (at least) deserialization to set final fields without needing to have
the actual security permission that setAccessible(true) expects. You should
still have to invoke setAccessible(true) of course. (This means that
setAccessible needs to see that the caller is readObject - but it also needs
to set some flag such that Field.set will only work if the target object is
'this' - which seems somewhat tricky to manage.)

Secondly, there must be some clear definitions for where "final field safe
contexts" exist. The new JLS defines this term for places where reflective
setting of final fields can be used safely/correctly, but nowhere (that I
could find) in the JDK 5.0 documentation does it state what constitute
"final field safe contexts" in that VM. In fact, it is worse than this - the
JLS leaves it up to an implementation to define "final field safe contexts",
so any such reliance on those contexts would be non-portable!

The Field.set documentation states:

"Setting a final field in this way is meaningful only during deserialization
or reconstruction of instances of classes with blank final fields, before
they are made available for access by other parts of a program. Use in any
other context may have unpredictable effects, including cases in which other
parts of a program continue to use the original value of this field."

But this is too informal - and what is "reconstruction of instances with
blank final fields"? Does that mean clone() - if so it needs to spell it
out. If not, then what?

The Serialization Specification (V1.5.0) does not mention final fields at
all! Let alone defining a "final field safe context".

So, I think the way forward with this is that:

a) "final field safe contexts" must be defined by the relevant
specifications eg. Serialization spec, and not left up to the VM.

b) The documentation for Field.Set needs to refer to "final field safe
context" to tie it back to the JLS. And reference any other spec/API that
defines such a context.

c) For Mustang, or Dolphin (?) we need to try to drop the need for the
security permission in deserialization

Peronally, I'm going to treat the possibility of setting final fields via
reflection as non-existent.

Cheers,
David Holmes

-------------------------------
JavaMemoryModel mailing list - http://www.cs.umd.edu/~pugh/java/memoryModel



This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:01:09 EDT