## exception handling

Exception test examples:

public native void testException1();

public static void main(String[] args) {

    JniTest test = new JniTest();

    try {
        test.testException();
        System.out.println("Program cannot continue 1, this sentence will not be printed \n");
    } catch (Throwable t) {
        System.out.println("Catch an exception thrown by JNI (Throwable), this will be printed" + t.getMessage() + "\n");
    }

    System.out.println("The program continues to execute 2, and the sentence will be printed \n");

}
Copy the code

C code is as follows:

JNIEXPORT void JNICALL Java_com_test_JniTest_testException1 (JNIEnv * env, jobject jobj){ jclass clz= (*env)->GetObjectClass(env, jobj); JfieldID jfieldID fid = (*env)->GetFieldID(env, CLZ, CLZ)"key1"."Ljava/lang/String;"); // This throws an exception that Java can catch through Throwableprintf("C can run , this will print"); Jstring key = (*env)->GetObjectField(env, jobj, fid) Char * c_str = (*env)->GetStringUTFChars(env, key, NULL);printf("C could not run , this will not print");
}
Copy the code

As you can see from the examples, the JNI layer throws an exception of the Error type. Java can catch the exception through Throwable or Error. After catching the exception, Java code can continue to execute.

##### To ensure that Java, C/C++ code can be executed properly, you need to:

Manually clear ExceptionClear in the JNI layer to ensure that the code can run. Remedies ensure that C/C++ code continues to run. Such as:

JNIEXPORT void JNICALL Java_com_test_JniTest_testException1 (JNIEnv * env, jobject jobj){ jclass clz = (*env)->GetObjectClass(env, jobj); JfieldID jfieldID fid = (*env)->GetFieldID(env, CLZ, CLZ)"key1"."Ljava/lang/String;");

    jthrowable err = (*env)->ExceptionOccurred(env);
    if(err ! (*env)->ExceptionClear(env); Fid = (*env)->GetFieldID(env, CLZ,"key"."Ljava/lang/String;");
    }


    jstring key = (*env)->GetObjectField(env, jobj, fid);
    char* c_str = (*env)->GetStringUTFChars(env, key, NULL);
}
Copy the code

The test code is as follows:

public static void main(String[] args) {

    JniTest test = new JniTest();

    try {
        test.testException();
        System.out.println("There is no exception in the program, this sentence will be printed \n");
    } catch (Exception e) {
        System.out.println("No exception thrown by JNI was caught, this sentence will not be printed" + e.getMessage() + "\n");
    }

    System.out.println("Program continues, this sentence will be printed \n");

}
Copy the code

The user can manually throw an exception through the ThrowNew function, which can also be caught by Java code:

JNIEXPORT void JNICALL Java_com_test_JniTest_testException (JNIEnv * env, jobject jobj){ jclass clz = (*env)->GetObjectClass(env, jobj); JfieldID jfieldID fid = (*env)->GetFieldID(env, CLZ, CLZ)"key1"."Ljava/lang/String;");

    jthrowable err = (*env)->ExceptionOccurred(env);
    if(err ! (*env)->ExceptionClear(env); Fid = (*env)->GetFieldID(env, CLZ,"key"."Ljava/lang/String;"); } jstring key = (*env)->GetObjectField(env, jobj, fid); char* c_str = (*env)->GetStringUTFChars(env, key, NULL); // The argument is not correct. The programmer throws an exception, which can be caught in Javaif (_stricmp(c_str,"efg") != 0){
        jclass err_clz = (*env)->FindClass(env, "java/lang/IllegalArgumentException");
        (*env)->ThrowNew(env, err_clz, "key value is invalid!"); }}Copy the code

The test code is as follows:

public static void main(String[] args) {

    JniTest test = new JniTest();

    try {
        test.testException();
        System.out.println("JNI manually threw an exception, Java will not continue, this sentence will not be printed \n");
    } catch (Exception e) {
        System.out.println("Caught an exception that JNI manually threw, this sentence will be printed:" + e.getMessage() + "\n");
    }

    System.out.println("Program continues, this sentence will be printed \n");

}
Copy the code

#### Summary of exception handling

JNI throws an exception of the Error type, which Java can catch through Throwable or Error. After catching an exception, Java code can continue to execute. At the C layer, ExceptionClear is allowed to ensure that the Java code in the try continues to execute, and it is best to provide a remedy to ensure that the JNI layer code continues to run normally. Exceptions thrown manually by the user through ThrowNew can also be caught in the Java layer.