I’ve been trying to get familiar with JNI and its functionality. I am trying to figure out how could I possibly keep reference to the Java environment. I am first calling native method that stores creates “NewGlobalRef” from the jobject and it works fine for a while. But then all the sudden I receive fatal error and log. I am pretty sure garbage collector removes something, even if I am keeping reference to the object all the time in both sides.
What I am doing atm is this
I call native method
myCoolObject.nativeMethod(otherCoolObject);
I am keeping reference to otherCoolObject all the time on java side. What the native method does is
JNIEXPORT void JNICALL Java_HelloWorld_nativeMethod(JNIEnv *env, jobject obj , jobject otherCoolObject) {
cout << "Called native method!" << endl;
coolObj = env->NewGlobalRef(otherCoolObject);
clazz = (*env).GetObjectClass(coolObj;
callbackEnv = env;
methodId = (*env).GetMethodID(clazz, "callback", "(II)V");
jint x = 1;
jint y = 2;
(*callbackEnv).CallVoidMethod(coolObj, methodId, x, y);
}
and I can call the method after this for a while but all the sudden it gives me fatal error I told you about
You can’t reuse your JNIenv, cause it’s specific to the function that created it (it’s thread, scope and all).
for getting a valid JNIenv for calling an java method from your callback you have to
use JNI_GetCreatedJavaVMs() and AttachCurrentThread()
more information here:
https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/invocation.html