Affects Version/s: None
Fix Version/s: 1.2
JDK version and platform:1.5.x
From mailing list:
Caluwaerts, Alain wrote on Tuesday, November 15, 2005 11:08 AM:
> I recently faced the same problem other people have with
> serializing/deserializing final fields using another JVM then the one
> provided by Sun. (for example JRockit) It has everything to do with
> not supporting the 'sun.misc.Unsafe' class.
> Normally final fields should only be used (in my humble opinion), as
> static final fields or as final Maps or Collections.
> I've tried to make a small change in following method in
> PureJavaReflectionProvider :
> protected void validateFieldAccess(Field field)
> if ((Modifier.isFinal(field.getModifiers())) &&
> (!Map.class.isAssignableFrom(field.getType())) && <---
> (!Collection.class.isAssignableFrom(field.getType()))) <---
> In other words, 'final Map' and 'final Collection' are allowed. And it
> works fine for JRockit 1.5.0_03 and Sun 1.5.0_05. (Forced to use
> I hope this small change can help a lot of people.
This is not a general solution. Field#set() of JDK 1.4 states:
"If the underlying field is final, the method throws an IllegalAccessException."
For JDK 1.5 the documentation has changed though:
"If the underlying field is final, the method throws an IllegalAccessException unless setAccessible(true) has succeeded for this field and this field is non-static. 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. "
So it is a new behaviour of JDK 1.5 and we can make exceptions if running under such a JDK. So your solution is just valid for actual JDKs not supporting the Sun14ReflectionProvider, implementations for older JDK versions without Sun14ReflectionSupport (as JRockit) will not work.