.java file:
class CatchThrow{
private native void doit()
throws IllegalArgumentException;
private void callback() throws NullPointerException{
throw new NullPointerException("CathThrow.callback");
}
public static void main(String args[]){
CatchThrow c = new CatchThrow();
try {
c.doit();
} catch (Exception e){
System.out.println("In Java:\n\t" + e);
}
}
static {
System.loadLibrary("CatchThrow");
}
}
.c file:
#include <jni.h>
#include <stdio.h>
#include "CatchThrow.h"
JNIEXPORT void JNICALL <span style="color:#000099;">Java_CatchThrow_doit //do it.</span>
(JNIEnv *env, jobject obj){
jthrowable exc;
jclass cls = (*env)->GetObjectClass(env,obj);
jmethodID mid = (*env)->GetMethodID(env, cls, "callback", "()V");
if (mid == NULL) return;
<span style="color:#000099;">(*env)->CallVoidMethod(env, obj, mid);//Invoke callback</span>
exc = (*env)->ExceptionOccurred(env);
if (exc){
jclass newExcCls;
<span style="color:#009900;">(*env)->ExceptionDescribe(env);//This stmt describes the stack trace.</span>
(*env)->ExceptionClear(env);
newExcCls = (*env)->FindClass(env, "java/lang/IllegalArgumentException");
if (newExcCls == NULL){
return;
}
(*env)->ThrowNew(env, newExcCls, "thrown from C code");
}
}
Result:
Exception in thread "main" java.lang.NullPointerException: CathThrow.callback
at CatchThrow.callback(CatchThrow.java:5)
at CatchThrow.doit(Native Method)
at CatchThrow.main(CatchThrow.java:10)
In Java:
java.lang.IllegalArgumentException: thrown from C code
JNI need to explicitly implement the control flow after an exception has occurred.