Suppose I have a Java class like this:
public class Test
{
static { System.loadLibrary("test"); }
public native int foo();
}
Suppose that the foo() method is doing some JNI calls, and one of these calls fails (IE, throws an exception). I would then like to return from the JNI code and have the exception thrown in Java. For example:
jint Java_Test_foo(JNIEnv* env, jobject thiz)
{
jstring foobar = (*env)->NewStringUTF(env, "Hello from JNI !");
if(foobar == NULL) // Not enough memory. OutOfMemoryError is thrown
return NULL; // Return immediately to get exception thrown in Java
// Do other stuff
...
return some_computed_jint;
}
The problem is that return NULL is not a jint. In Android for example, I would get this warning when compiling:
warning: return makes integer from pointer without a cast.
Now the question is: What should I return in case of an Exception being thrown inside a JNI method that returns a jint?
If your code (or a library) raises an
Exceptionin Java, it doesn’t matter what value you return, Java will ignore it. Obviously it needs to be a compatible type – so returning0in your example would seem to make sense, or whatever you’re comfortable with. When your code returns, the Java runtime will notice that anExceptionhas been raised and continue to propagate it and ignore the return value of your function.You will, of course, need to return a compatible type. Don’t simply return
NULL, as that will be cast to anintwhen the function is not declared to return a pointer, which may not be appropriate.Obviously, though, when you’re calling C functions, those would not raise an
Exception. So you can either map an integer to an error condition (-1for example) and then throw theExceptionin Java, or you can take the time to build anExceptionin JNI.