I'm attempting to create a C++ callback that gets called if a certain event occurs. That callback is supposed to call a Java method if that is the case.
In order to be able to call that Java method I need access to the JNIEnv object which is why I set everything up in a JNI function which gets called from Java.
Setting things up is straight forward. I obtain the jclass
, the jmethodID
, etc. within the JNI function. The code looks as follows:
JNIEXPORT void JNICALL Java_my_customclass_register(JNIEnv* jenv, jobject obj, jlong nativePeerAddress, jstring callbackName)
{
jclass customClass = jenv->FindClass("<fully qualified class name>");
const char* methodName = jenv->GetStringUTFChars(callbackName, JNI_FALSE);
jmethodID callbackMethod = jenv->GetMethodID(customClass, methodName, "()V");
jenv->ReleaseStringUTFChars(callbackName, methodName);
reinterpret_cast<CustomClass*>(nativePeerAddress)->SetCallback([jenv, obj, callbackMethod]()
{
jenv->CallVoidMethod(obj, callbackMethod);
});
}
The line with the SetCallback
call is where the C++ lambda that acts as callback gets set. The callback itself eventually, once the event occurs, calls the Java method using the line
jenv->CallVoidMethod(obj, callbackMethod);
The problem I'm facing is that this call happens long after the above listed JNI method terminated. If the callback gets invoked I eventually get the following error message:
JNI DETECTED ERROR IN APPLICATION: use of invalid jobject
That call succeeds as expected if I move that line of code out of the C++ callback and place it right below the line
jenv->ReleaseStringUTFChars(callbackName, methodName);
However, it does not work when executed from within the C++ callback. I think the problem here is that the jobject
obj
is longer a valid object. My assumption is that this is the case because the JNI method already terminated and disposed the jobject
(the C++ wrapper, not the Java object).
However, it is unclear to me how I can obtain a valid jobject
on which I can execute the jmethodID
. obj
would point to the right Java object but it is just not working that way.
Any ideas how I can get a valid jobject
?