JNI/NDK Development Guide (11) -- JNI Exception Handling, ndkjni

Source: Internet
Author: User

JNI/NDK Development Guide (11) -- JNI Exception Handling, ndkjni

Reprinted please indicate the source: http://blog.csdn.net/xyang81/article/details/45770551

Exception description

Exception. The explicit opinion is that the program is not executed according to the normal program logic during the running process, and some errors occur during the execution process, causing the program to crash. In Java, exceptions are divided into runtime exceptions (RuntimeException) and compile-time exceptions. We will use try... Catch... If the program is not processed, an exception occurs during the running process, causing the program to crash. During compilation, exceptions must be handled during compilation. This chapter describes exceptions during running.
Example 1:

// Public static void exceptionCallback () {int a = 20/0; System. out. println ("--->" + );}

Example 2:

// Exception during compilation public static void testException () throws Exception {//... System. out. println ("testException () invoked! ");} Public static void main (String [] args) {exceptionCallback (); try {testException ();} catch (Exception e) {e. printStackTrace ();}//....}
In Example 2, when the testException method is declared, a java. lang. Exception is thrown. Therefore, try... catch must be used to handle the Exception.

As we all know, if the main method in example 2 is executed to call the exceptionCallback method, the first line of the method has an operation except 0, so this method will throwjava.lang.ArithmeticExceptionThe main method does not handle any exceptions that may occur when the function is running. Therefore, the program ends immediately, and the subsequent Codetry{testException();}catch(Exception e) {e.printStackTrace();}Will not be executed. Run the Example 2 program and you will see the following results:

Exception in thread "main" java.lang.ArithmeticException: / by zero    at com.study.jnilearn.JNIException.exceptionCallback(JNIException.java:8)    at com.study.jnilearn.JNIException.main(JNIException.java:22)

Let's improve the above program:

public static void main(String[] args) {    try {        exceptionCallback();    } catch (Exception e) {        e.printStackTrace();    }    try {        testException();    } catch (Exception e) {        e.printStackTrace();    }}

Then we run the program and callexceptionCallbackMethodjava.lang.ArithmeticException: / by zeroException because we use try... The catch Block shows that the exception is handled, so the program will continue to execute, call the testException () function, and printtestException() invoked!. The running result is as follows:

java.lang.ArithmeticException: / by zero    at com.study.jnilearn.JNIException.exceptionCallback(JNIException.java:8)    at com.study.jnilearn.JNIException.main(JNIException.java:24)testException() invoked!
Differences between Java and JNI Exception Handling

The following is a summary:
1. in Java, If you think a logic segment may cause exceptions, use try... Catch mechanism to capture and handle exceptions
2. If a runtime exception occurs in Java, try… is not used... Catch will cause the program to crash and exit,Subsequent code will not be executed
3. An exception occurs during compilation. When a method is declared, throw is used to declare an exception. The Compiler requires that the capture process be displayed during the call.
public static void testException() throws Exception {}
All the friends who have written Java above know this and it is very simple. But why do I have to come up with it? What I want to emphasize is, exceptions in JNI are completely different from those in Java.When we write a JNI program, JNI does not have a try like Java... Catch... If an exception occurs when calling a JNI interface in the local code, the subsequent local code will not immediately stop the execution, and will continue to execute the subsequent code.

Exception Handling example

Example 3:
In this example, the local doit method is called in main.exceptionCallbackMethod, this method will cause a running exception except 0java.lang.ArithmeticException, We use this example to learn how to correctly handle such exceptions in JNI.

package com.study.jnilearn;public class JNIException {    public static native void doit();    public static void exceptionCallback() {        int a = 20 / 0;        System.out.println("--->" + a);    }    public static void normalCallback() {        System.out.println("In Java: invoke normalCallback.");    }    public static void main(String[] args) {        doit();    }    static {        System.loadLibrary("JNIException");    }}
/* Do not edit this file-it is machine generated */# include <jni. h>/* Header for class com_study_jnilearn_JNIException */# ifndef _ EXIST # define _ EXIST # ifdef _ cplusplusextern "C" {# endif/** Class: com_study_jnilearn_JNIException Method: doit * Signature: () V */JNIEXPORT void JNICALL Java_com_study_jnilearn_JNIException_doit (JNIEnv *, jclass); # ifdef _ cplusplus} # endif // JNIException. c # include "com_study_jnilearn_JNIException.h" # include <stdio. h> JNIEXPORT void JNICALL extends (JNIEnv * env, jclass cls) {jthrowable exc = NULL; jmethodID mid = (* env)-> GetStaticMethodID (env, cls, "exceptionCallback ", "() V"); if (mid! = NULL) {(* env)-> CallStaticVoidMethod (env, cls, mid);} printf ("In C: Java_com_study_jnilearn_JNIException_doit --> called !!!! "); If (* env)-> ExceptionCheck (env) {// check whether JNI call has thrown an exception (* env)-> ExceptionDescribe (env ); (* env)-> ExceptionClear (env); // clear the thrown exception. The Java layer does not print the stack information (* env)-> ThrowNew (env, (* env)-> FindClass (env, "java/lang/Exception"), "exceptions thrown by JNI! "); // Return;} mid = (* env)-> GetStaticMethodID (env, cls," normalCallback "," () V "); if (mid! = NULL) {(* env)-> CallStaticVoidMethod (env, cls, mid );}}

The program running result is as follows:

Exception in thread "main" java. lang. arithmeticException:/by zero at com. study. jnilearn. JNIException. exceptionCallback (JNIException. java: 8) at com. study. jnilearn. JNIException. doit (Native Method) at com. study. jnilearn. JNIException. main (JNIException. java: 17) Exception in thread "main" java. lang. exception: An Exception thrown by JNI! At com. study. jnilearn. JNIException. doit (Native Method) In Java: invoke normalCallback. at com. study. jnilearn. JNIException. main (JNIException. java: 17) In C: Java_com_study_jnilearn_JNIException_doit --> called !!!!

After the local doit method is called in the Main method, the control of the program is handed over to JNI. In the local doit method, the exceptionCallback method is called back, causingjava.lang.ArithmeticExceptionException, but the local interface does not exit immediately, but will continue to execute the subsequent code. Therefore, after calling any JNI interface, one thing that must be done is to check whether an exception has occurred in this JNI call. If an exception does not occur and the program continues to execute the subsequent logic, unpredictable consequences will occur. In this example, we callExceptionCheckFunction check whether an exception has occurred in the last JNi call. If any exception occurs, this function returns JNI_TRUE; otherwise, JNI_FALSE. When an exception is detected, we callExceptionDescribeThe function prints the stack information of this exception and then callsExceptionClearThe function clears the buffer of the exception stack information (if not cleared, the exception stack information thrown by the subsequent call ThrowNew overwrites the previous exception information), and finally callsThrowNewThe function manually throws a java. lang. Exception. However, the uncaptured exceptions thrown in JNI are different from the Exception Handling Mechanism in Java. In JNI, the execution of local methods is not terminated immediately, but the subsequent code is executed. In this case, we need to handle it manually. In the 38 rows in the example, if you do not need to return and exit the method immediately, the code after 37 rows ThrowNew will continue to be executed. If the program runs the same result, the code will still be called back.normalCallbackMethod to print out: invoke normalCallback.
The exception check JNI also provides another interface,ExceptionOccurredIf an exception is detected, the function returns a reference pointing to the current exception. Functions andExceptionCheckThe difference between the two is that the return values are different. Let's rebuild the example above:

//.... Jthrowable exc = NULL; exc = (* env)-> ExceptionOccurred (env); // returns a reference to the current exception object if (exc) {(* env) -> ExceptionDescribe (env); // print the exception stack information thrown by the Java layer (* env)-> ExceptionClear (env ); // clear the Exception information // throw our own Exception to handle jclass newExcCls; newExcCls = (* env)-> FindClass (env, "java/lang/Exception "); if (newExcCls = NULL) {return;} (* env)-> ThrowNew (env, newExcCls, "throw from C Code. ");}//....
Write a tool class that throws an exception

When you need to throw your own exception processing logic, you need to take two steps to call FindClass to locate the Exception Processing class and then call ThrowNew to throw an exception. To simplify the operation process, we write a tool function to generate an exception with a specified name based on an exception class name:

Void JNU_ThrowByName (JNIEnv * env, const char * name, const char * msg) {// find the exception class jclass cls = (* env)-> FindClass (env, name ); /* if this exception class is not found, the VM will throw a NowClassDefFoundError exception */if (cls! = NULL) {(* env)-> ThrowNew (env, cls, msg); // throw an exception with the specified name}/* release a local reference */(* env) -> DeleteLocalRef (env, cls );}
Release resources when exceptions occur

Releasing resources after an exception occurs is very important. In the following example, after calling the GetStringChars function, if the following code has an exception, call ReleaseStringChars to release the resource.

JNIEXPORT void JNICALL Java_pkg_Cls_f (JNIEnv * env, jclass cls, jstring jstr) {const jchar * cstr = (* env)-> GetStringChars (env, jstr ); if (c_str = NULL) {return ;}... if (* env)-> ExceptionCheck (env) {/* exception check */(* env)-> ReleaseStringChars (env, jstr, cstr ); // release the previously allocated memory return after an exception occurs ;}... /* normal return */(* env)-> ReleaseStringChars (env, jstr, cstr );}
Summary

1. After calling a JNI function, you must check, process, and clear the exceptions before calling other JNI functions. Otherwise, unpredictable results may occur.
2. If an exception occurs, return immediately and ask the caller to handle the exception. Or call ExceptionClear to clear the exception and execute your own exception handling code.
3. Summary of JNI functions related to exception handling:
1> ExceptionCheck: Check for exceptions. If any exception occurs, JNI_TRUE is returned. Otherwise, JNI_FALSE is returned.
2> ExceptionOccurred: Check whether an exception has occurred. if an exception is used, a reference to the exception is returned. Otherwise, NULL is returned.
3> ExceptionDescribe: prints abnormal stack information
4> ExceptionClear: clears the exception stack information.
5> ThrowNew: triggers an exception in the current thread and outputs the exception information customized.
jint (JNICALL *ThrowNew) (JNIEnv *env, jclass clazz, const char *msg);
6> Throw: discard an existing exception object and trigger a new exception in the current thread.
jint (JNICALL *Throw) (JNIEnv *env, jthrowable obj);
7> FatalError: Fatal exception. It is used to output an exception message and terminate the current VM instance (that is, exit the program)
void (JNICALL *FatalError) (JNIEnv *env, const char *msg);

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.