Reputation: 15093
I'm implementing some JNI callback (native -> java) functionality alongside another larger native framework and on one of the framework's callbacks I'm getting this error when trying to callback to java.
FATAL Error in native method: Using JNIEnv in non-java thread
What exactly does this mean? What is a java-thread and how do I go about using JNI in another native thread?
Upvotes: 2
Views: 2093
Reputation: 15093
Java must be attached to the thread on which it is to be executing.
The JNI interface pointer (
JNIEnv
) is valid only in the current thread. Should another thread need to access the Java VM, it must first call AttachCurrentThread() to attach itself to the VM and obtain a JNI interface pointer. Once attached to the VM, a native thread works just like an ordinary Java thread running inside a native method.
To do this, you must store a pointer to the JVM object, either through the JNI_OnLoad()
export or by storing it via a JNI native
call you've implemented using (JNIEnv*)java->GetJavaVm(&(JavaVM*)jvm);
.
From there, each time you need to use JNI, simply call the following in order to attach to the current thread and retrieve a new JNIEnv*
pointer.
JNIEnv* AttachJava()
{
JavaVMAttachArgs args = {JNI_VERSION_1_2, 0, 0};
JNIEnv* java;
jvm->AttachCurrentThread((void**) &java, &args);
return java;
}
Do not save instances of JNIEnv*
unless you are sure they will be referenced in the same thread.
As the documentation states, calling AttachCurrentThread
on an already attached thread is a no-op and thus is innocuous.
Upvotes: 8