Say I have the following Java code:
public class Test {
public static int foo() {
throw new RuntimeException();
}
}
which loads a native library in the usual manner. The native library registers and caches the JVM or whatever, and then, later on, this function gets executed:
JNIEnv* sEnv; // initialised somewhere properly
void throwMeARiver() {
jclass c = sEnv->FindClass("Test");
jmethodID m = sEnv->GetStaticMethodID(c, "foo", "()I");
jint i = sEnv->CallStaticIntMethod(c, m);
printf("Got %d\n", (int)i);
}
Evidently sEnv->CheckException() will now return JNI_TRUE, but what will the native function print out? In Java, throwing an Exception makes the JVM stop executing the method it's in until it finds an appropriate handler, so foo()'s return value is undefined. So is i also undefined?
I can't find any specs or anything saying otherwise, so presumably i /is/ undefined. There's no 'normal' range of CallStaticIntMethod in this case, unlike most JNI functions.
I'm trying this now, but I'm mainly asking this to see if there's a mandated behaviour somewhere.
While the variable i will be defined, its value is undetermined. In this situation, most likely, the value will be 0, but only if the JVM initialized the value in its implementation. Otherwise, it will be equal to whatever the data is present at its location in memory.
Its up to the implementer of the native function to properly check for an exception following a CallXXXMethod()
via env->CheckException()
, env->ExceptionOccurred()
, and env->ExceptionDescribe()
. Finally, a call to env->ClearException()
to remove the exception.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With