6

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.

allicoder
  • 285
  • 1
  • 7

2 Answers2

2

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.

Samhain
  • 1,767
  • 1
  • 12
  • 20
  • 1
    from my tests on Android, the value returned is whatever happens to be in some unpredictable memory location. – Alex Cohn Oct 03 '13 at 07:08
-1

No, JNI CheckException() is not equivalent to Java try … catch, therefore your new RuntimeException() will propagate further and maybe not get caught at all.

Thanks to @EJP for correcting me: actually, any Throwable from Java is intercepted by the C/C++ caller. From my tests on Android, the value returned is whatever happens to be in some unpredictable memory location (stack?).

For more discussion of JNI and exceptions, see How to catch JNI/Java Exception.

Community
  • 1
  • 1
Alex Cohn
  • 56,089
  • 9
  • 113
  • 307
  • He didn't ask whether it was equivalent to Java `try.` He asked what the return *value* was, and you haven't answered him. Your answer implies that that `CheckException()` won't return true for a `RuntimeException,` which isn't correct. – user207421 Oct 01 '13 at 22:01
  • @EJP That should be "she"/"her". – allicoder Oct 02 '13 at 09:36
  • @EJP: thanks, I was wrong: actually, any Throwable from Java is intercepted by the C/C++ caller. Every day I learn something new. – Alex Cohn Oct 03 '13 at 07:19