Date: Thu, 06 May 2004 13:50:58 -0400
JSR133 requires that all fields of classes that are specified to be
immutable must be declared as "final". This solves a long-standing
issue in the memory semantics of Java that was not addressed in the
original JLS. The presense of "final" in such cases is more than a
decoration. It causes the compiler and hardware to not reorder
critical instructions in a way that could cause one thread to "catch"
an immutable object in the course of construction, and thus see its
pre-construction (0/null) value instead of its actual final
value. This is not just a theoretical possibility; without the use of
"final", this can and does occur regularly on multiprocessors. A
further discussion with examples of how this may induce security holes
may be found at
As part of JSR133, the expert group surveyed all classes in java.lang
and java.util, to find those that required field declarations be
marked as "final" to meet their specs. This was then done as bug
While this is all fine, the JSR133 group did not address (or
anticipate the consequences of) a known interaction between "final"
and code that does "manual" deserialization, such as the XML
serialization in appServer: It is impossible to reflectively assign a
value to a final field. Thus, appServer broke. This might be
indicative of other similar code out there also being broken.
While it might be deal with this by undoing some of the "finals" in
4998264, this would be a crummy alternative in two senses: (1) It
merely delays the day of reckoning for dealing with the underlying
problem (2) People writing multithreaded code will be relying on
immutability guarantees that are not actually supported, so will
encounter extremely difficult to locate bugs.
Allow reflective set-field operations on any final field f,
ONLY if f.setAccessible(true) succeeds.
1. appServer will actually work. (Not just sort-of work, as true even
when using 1.4.x). Any other similar code out there that bothers
to do explicit setAccessible calls before setting fields will
2. In some limited circumstances, this technique can be used in
a serializable class's custom readObject method to initialize
final fields upon deserialization directly (rather than through
defaultReadObject). Note that because of the permission
requirement, this only applies to highly trusted code; it is not
a general solution.
3. No API change. It only requires addition of one new sentence in
the javadocs to describe the case when setting final is allowed.
4. By requiring the setAccessible check EVEN if the field is
public, there is essentially no possibility of accidental misuse.
5. If you have permission to suppress all access checks, then you can,
among other things change the security manager, so there is
no additional security risk here.
6. Bill Pugh and I can/will adjust the JSR133 spec to add the appropriate
wording about resulting multithreaded semantics.
7. There is almost no impact on plans to further optimize final fields
in the future inside hotspot.
8. And mainly: I think this is the simplest solution that actually works.
1. While the changes are straightforward, there are more lines of
them than anyone wants to see at this point.
2. If people use this in inappropriate contexts (i.e., in situations
not related to object reconstruction or deserialization)
their programs will make no sense.