Search code examples
exceptionjava-native-interfaceandroid-ndkjint

JNI int method returning from exception


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?


Solution

  • If your code (or a library) raises an Exception in Java, it doesn't matter what value you return, Java will ignore it. Obviously it needs to be a compatible type - so returning 0 in your example would seem to make sense, or whatever you're comfortable with. When your code returns, the Java runtime will notice that an Exception has 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 an int when 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 (-1 for example) and then throw the Exception in Java, or you can take the time to build an Exception in JNI.