givi
givi

Reputation: 1903

JNI parameters are local or global references

I've read several references about local and global references in JNI. But I couldn't find a definite answer whether Java object which is passed as parameter to the JNI function is local or global reference. I supposed that it should be global, however there is one problem:

First I get the Java-object pointer and save it. Then the native callback function calls method of that object. The callback function is called from a separate thread. The thread was created using AttachCurrentThread(), so JVM knows about it. JNIEnv* variable is also valid and the object was not garbage callected, however I get warning and then crash.

JNI WARNING: 0x4108edb8 is not a valid JNI reference in Lcom/my/company/MyClass;.load:(Ljava/lang/String;)V (GetObjectClass)

Upvotes: 1

Views: 2978

Answers (2)

Fredrik
Fredrik

Reputation: 5839

Theoretically you can get a global ref if the function is not called from Java code (I sometimes call my JNI methods directly from other JNI methods without asking the JVM to do it) but you should always assume them to be local and treat them like that. If you want to store them for later use, you should create a new gobal reference. In fact, even if you could get a global ref, there would be no difference in how you should treat them. You don't have to delete them in any case and even if you do happen to get a global reference (I think the way described above is the only way), storing it without first making a new reference of it would be wrong. If whoever gave it to you deletes the ref it will turn invalid.

Edit: The above is an edited version which I hope will satisfy @EJP more. Same message, just clearer. And he does have a point that for almost all cases, the JNI spec is all that matters even if it makes no difference in this case :-)

Upvotes: 0

user207421
user207421

Reputation: 310860

  1. It's a local reference. "Objects are passed to native methods as local references"

  2. JNIEnv* pointers are not valid across JNI method call boundaries let alone thread boundaries.

  3. In your circumstance you must convert the local reference to a global reference for use by the callback method.

Upvotes: 5

Related Questions