简体   繁体   中英

Is there a way to force Java VM to execute immediately an exception sent from JNI?

I need to send an exception in Java from the main jni-thread. I use the following code to do such a thing:

if (vm->AttachCurrentThread(reinterpret_cast<void **>(&env), nullptr) != JNI_OK || env == nullptr) {
    std::cerr << "Get env for current thread failed.\n";
    return ;
}
jclass exClass = env->FindClass("[JavaClassName]");
if (exClass != nullptr) {
    env->ThrowNew(exClass, "[ExceptionMessage]");
}
env->DeleteLocalRef(exClass);
vm->DetachCurrentThread();

It somehow works. I have found out that if we don't use the attach and detach (just use only the throw) then the exception raises only after the jni-call from Java VM is finished. If we use the attach and detach then the exception raises in the detach call. Is it a correct way to make things faster? I don't still understand why the exception processing is deferred until a call to DetachCurrentThread()? I use Android. Thank you very much.

The Java interpreter attached to your current thread is not running whilst you are in the JNI code. So there is no way to process the exception on the Java side (unwind stack frames, catch etc). The Java exception is created as pending and only really thrown when the JNI call returns to Java and the execution of the interpreter continues for your current Java thread.

Detaching sort of fakes this process but could leave your JNI code in an unstable state: Java is now running, JNI has not returned and is still running your code.

My preferred solution is to throw the Java exception as you do and immediately throw a C++ exception which is only (and must be) caught at the JNI boundary and discarded. The C++ exception is thrown purely to cause stack unwinding and a quick clean exit from the JNI call.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM