A java class does something like the following
public class Foo {
private final NativeCallbackHandler handler;
public Foo(NativeCallbackHandler handler) {
// I've shortened this for exposition, callSomeNativeMethod
// really happens in a superclass that I don't own (and is
// part of the lib that gives me the native part)
callSomeNativeMethod();
this.handler = handler;
}
public void handleNativeCallback(Object args) {
this.handler.callback(args);
}
private native int callSomeNativeMethod();
}
You can assume that the native method does something that can lead to native code calling handleNativeMethod
I have 2 related questions
- I believe the native code must call have a handle on this object and also call
GetMethodIDto get access to the method to call, is it possible for that native code to call the method before the object is fully initialised? - If it can, what are the semantics of an uninitialised final field?
if 1 is yes then I expect 2 to blow up on access it and hence I imagine we’d need to make it an AtomicReference in order to access it safely without blowing up.
Note I have no control over the behaviour of the native library.
Looks like it is possible. Native code does not enforce the
finalrestriction.From http://java.sun.com/docs/books/jni/html/pitfalls.html#36197:
This doesn’t define behavior when you access an uninitialized final reference, but we can probably make a fairly good guess.
Personally, I would try to avoid the problem, either by: