Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 5044412
Votes 0
Synopsis (reflect) if setAccessible(true) has succeeded, allow final fields to be set
Category java:classes_lang
Reported Against tiger-beta2
Release Fixed 1.5(tiger-b51)
State 10-Fix Delivered, bug
Priority: 2-High
Related Bugs 6379948 , 4998264 , 5041458 , 5046584 , 5046585 , 5040310 , 5081108 , 5103437
Submit Date 10-MAY-2004
Description
Date: Thu, 06 May 2004 13:50:58 -0400 



Background: 
 
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  customer  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 
http://www.cs.umd.edu/users/pugh/java/memoryModel/jsr-133-faq.html#finalWrong 
 
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 
4998264. 
 
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. 
 
Proposal:  
  Allow reflective set-field operations on any final field f, 
  ONLY if f.setAccessible(true) succeeds. 
 
Advantages: 
  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 
     similarly work.
  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  customer  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. 
 
Disadvantages: 
  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  customer  reconstruction or deserialization)  
     their programs will make no sense. 
Work Around
N/A
Evaluation
This should be considered for tiger-beta2.

--   xxxxx@xxxxx   2004-05-10
Comments
  
  Include a link with my name & email   

Submitted On 02-MAR-2005
davidholmes
Why did you not do this such that ONLY custom deserialization could invoke setAccessible(true) on a final field, without needing security permissions? Why allow arbitrary code to set final fields if it makes no sense (with regards to JMM) unless done in deserialization? And what use is it if custom deserialization requires explicit permission to set a final field?

This is a mess! The only thing "fixed" is appServer.


Submitted On 22-SEP-2005
4894114
Is there any possibility to get this back-ported to java 1.4.x?


Submitted On 22-SEP-2005
4894114
>This is a mess! The only thing "fixed" is appServer.

I don't think so. If the security manager allows changing the property, even other libraries can take advantage of that feature.

For example, custom database persisters, JDO or any other reflection tool that serialize/persists objects.



PLEASE NOTE: JDK6 is formerly known as Project Mustang