Can a JNI call a method on an object during initialization?

The 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(); } 

We can assume that the native method does something that could lead to the creation of our own code that calls handleNativeMethod

I have 2 related questions

  • I believe that native code should call to have a handle to this object, and also call GetMethodID in order to access the called method, is it possible for this native code to call the method before the object is fully initialized?
  • If possible, what is the semantics of the uninitialized final field?

if 1 is yes, then I expect 2 to explode its access, and I think we need to make it an AtomicReference in order to safely access it without an explosion.

Note. I do not control the behavior of my own library.

+4
source share
2 answers

It seems like it's possible. Parent code does not apply the final constraint.

From http://java.sun.com/docs/books/jni/html/pitfalls.html#36197 :

10.9 Violation of access control rules

JNI does not apply a class, field, or access restriction to a method that can be expressed at the Java level of a programming language through the use of modifiers such as private and final. You can write native code to access or change the fields of an object, even if this is done at the Java programming language level, an IllegalAccessException will be thrown. JNI's permissibility was a conscious design decision, given that the code can access and change any memory location on the heap anyway.

Source code that bypasses access control at the source language level can have an undesirable effect on program execution. For example, inconsistency can be created if the native method changes the final field after the Just-in-time (JIT) compiler has built-in access to the field. Similarly, native methods should not modify immutable objects, such as fields in cases of java.lang.String or java.lang.Integer. This can break invariants in the Java platform implementation.

This does not determine the behavior when accessing an uninitialized final link, but we can probably make a pretty good guess.

Personally, I will try to avoid the problem, either:

  • Make sure everything was initialized before the callback
  • Do nothing during the callback until a flag is set that completes the initialization.
+3
source

A call to handleNativeCallback from the constructor of the superclass will result in a NullPointerException because it is called before setting the handler. It makes no difference whether the call was made by JNI or pure Java code.

+2
source

All Articles