Firstly, since a native method could be called from a constructor to
initialize its final fields it doesn't seem reasonable to disallow JNI code
from modifying final fields completely.
Secondly, I think a semantics can be specified in a reasonably clean way
that doesn't constrain compilers.
We say that writes to final fields in JNI (outside the constructor of the
object containing the field) add to "allWrites", but not to "previous". And
that such writes to not modify "overriden". In effect whether these writes
do anything at all becomes implementation specific. That is, we define
allWrites += <v,w,g>
Then we need to specify which JNI to Final fields use writeJNIFinal and
which use writeFinal. Specifically they all use writeJNIFinal except
A. When they are writing the field of an object whose constructor has not
B. During some (yet to be determined) times associated with deserialization.
Granted B is ugly, but as has been noted previously some exceptions need to
be made for serialization.
Note that this leaves JIT's free to assume that final fields are never
changed (outside the constructor or deserialization).
At 06:44 PM 06/11/2001, Bill Pugh wrote:
>>I've said this before but I'll repeat it. I don't think the JSR will have
>>any chance of changing JNI to prevent modifications to final fields, for a
>>variety of reasons. But it is also not necessary to prevent it. Use of
>>native code turns off all safety guarantees and so we need not be concerned
>>about what native code does with regard to synchronization, in general.
>I feel pretty strongly about this. When somebody writes an article for
>JavaWorld advocating the use of JNI to change final fields in custom
>deserialization, I think we need one of three things to be true:
>* JNI throws an exception if an attempt is made to change a final field.
>* I can go to the specification and point to a place where is says: "If you do
> this, the semantics of your program are completely undefined, and your
> VM can core dump or produce corrupt and non-typesafe results."
>* The spec defines the semantics of using JNI to change final fields.
>(This excludes the write protected fields such as System.in, for which
>some special case will be provided).
>I don't think any other answer is acceptable. If there is any idiom that
>JVMs are going to be required to support, the semantics of the VM must
>define that support. You can't have VM requirements that are not supported
>by the semantics.
>And if we don't declare using JNI to change final fields to be broken,
>then you can count on somebody with poor taste using it and then demanding
>that JVM's support it. And if they are an important application/company,
>I don't feel strongly about whether JNI needs to throw an exception. The
>spec just needs to say whether the semantics are defined. (If the
>semantics are not
>defined, at least the debug version of JNI should report an error).
>This is similar to what happens when a constructor makes an object visible
>to other threads before the object is completely constructed. I don't
>recommend it, but the spec has to specify the semantics of doing so.
>JavaMemoryModel mailing list - http://www.cs.umd.edu/~pugh/java/memoryModel
JavaMemoryModel mailing list - http://www.cs.umd.edu/~pugh/java/memoryModel
This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:00:32 EDT