如何从JNI中捕获的Java异常中获取消息

flu*_*ffy 3 java java-native-interface

我试图捕获Java抛出的异常并将异常消息报告给我自己的日志框架.但是,如果我这样做,就会出现明显的鸡蛋问题; 我正在尝试使用Java getMessage()调用获取消息:

jthrowable e = env->ExceptionOccurred();
jclass clazz = env->GetObjectClass(e);
jmethodID getMessage = env->GetMethodID(clazz,
                                        "getMessage",
                                        "()Ljava/lang/String;");
Run Code Online (Sandbox Code Playgroud)

但我实际上无法解析getMessage,因为挂起的异常导致JVM在我调用时中止GetObjectClass.

是否有一种安全的方法可以预先获得jmethodID所有例外情况?如果我只是Throwable.getMessage()在应用程序启动时获取方法ID ,那么它是否jmethodID可以移植到其他类?或者是适当的方法来调用env->ExceptionClear()并继续使用相同的本地jthrowable引用?

flu*_*ffy 6

以下作品; 但是,我不知道这是否是正确的方法:

jthrowable e = env->ExceptionOccurred();
env->ExceptionClear(); // clears the exception; e seems to remain valid

jclass clazz = env->GetObjectClass(e);
jmethodID getMessage = env->GetMethodID(clazz,
                                        "getMessage",
                                        "()Ljava/lang/String;");
jstring message = (jstring)env->CallObjectMethod(e.get(), getMessage);
const char *mstr = env->GetStringUTFChars(message, NULL);
// do whatever with mstr
env->ReleaseStringUTFChars(message, mstr);
env->DeleteLocalRef(message);
env->DeleteLocalRef(clazz);
env->DeleteLocalRef(e);
Run Code Online (Sandbox Code Playgroud)

  • 除非该方法继续使用许多其他方法,否则您实际上并不需要所有这些 `DeleteLocalRef()` 调用。当 JNI 方法退出时,引用将被删除。+1 (2认同)