Friday, April 19, 2013

jni jnienv ExceptionClear example c c++ java


ExceptionClear


void ExceptionClear(JNIEnv *env);

Clears any exception that is currently being thrown. If no exception is currently being thrown, this routine has no effect.

LINKAGE:
Index 17 in the JNIEnv interface function table.
PARAMETERS:

env: the JNI interface pointer.
Example of ExceptionClear

#include <stdlib.h>       /* malloc, free, and so forth */
#include <stdio.h>        /* fprintf(), and so forth */
#include <qtqiconv.H>     /* iconv() interface */
#include <string.h>       /* memset(), and so forth */
#include "NativeHello.h"  /* generated by 'javah-jni' */
 
/*  All literal strings are ISO-8859-1 Latin 1 code page (and with 7-bit
characters, they are also automatically UTF-8). */
#pragma convert(819)  /* handle all literal strings as ASCII */
 
/*  Report and clear a JNI exception. ExceptionClear  */
static void HandleError(JNIEnv*);
 
/*  Print an UTF-8 string to stderr in the coded character */
set identifier (CCSID) of the current job.  */
static void JobPrint(JNIEnv*, char*);
 
/*  Constants describing which direction to covert:  */
#define CONV_UTF2JOB 1
#define CONV_JOB2UTF 2
 
/*  Convert a string from the CCSID of the job to UTF-8, or vice-versa.  */
int StringConvert(int direction, char *sourceStr, char *targetStr);
 
/*  Native method implementation of 'setTheString()'.  */
 
JNIEXPORT void JNICALL Java_NativeHello_setTheString
(JNIEnv *env, jobject javaThis)
{
    jclass thisClass;     /* class for 'this' object */
    jstring stringObject; /* new string, to be put in field in 'this' */
    jfieldID fid;         /* field ID required to update field in 'this' */
    jthrowable exception; /* exception, retrieved using ExceptionOccurred */
 
    /*  Write status to console.  */
    JobPrint(env, "( C ) In the native method\n"); 
 
    /* Build the new string object.  */
    if (! (stringObject = (*env)->NewStringUTF(env, "Hello, native world!")))
    {
        /*  For nearly every function in the JNI, a null return value indicates
        that there was an error, and that an exception had been placed where it
        could be retrieved by 'ExceptionOccurred()'. In this case, the error
        would typically be fatal, but for purposes of this example, go ahead
        and catch the error, and continue. ExceptionClear */
        HandleError(env);
        return;
    }
 
    /* get the class of the 'this' object, required to get the fieldID  */
    if (! (thisClass = (*env)->GetObjectClass(env,javaThis)))
    {
        /*  A null class returned from GetObjectClass indicates that there
        was a problem. Instead of handling this problem, simply return and
        know that the return to Java automatically 'throws' the stored Java
        exception.  */
        return;
    }
        
    /*  Get the fieldID to update.  */
    if (! (fid = (*env)->GetFieldID(env,
                                    thisClass,
                                    "theString",
                                    "Ljava/lang/String;")))
    {
        /*  A null fieldID returned from GetFieldID indicates that there
        was a problem.  Report the problem from here and clear it.
        Leave the string unchanged.  ExceptionClear */
        HandleError(env);
        return;
    }
 
    JobPrint(env, "( C ) Setting the field\n");
 
    /*  Make the actual update.
    Note: SetObjectField is an example of an interface that does
    not return a return value that can be tested.  In this case, it
    is necessary to call ExceptionOccurred() to see if there
    was a problem with storing the value  */
    (*env)->SetObjectField(env, javaThis, fid, stringObject);
 
    /*  Check to see if the update was successful. If not, report the error.  */
    if ((*env)->ExceptionOccurred(env)) {
 
        /*  A non-null exception object came back from ExceptionOccurred,
        so there is a problem and you must report the error. */
        HandleError(env);  
    }
 
    JobPrint(env, "( C ) Returning from the native method\n");
    return;
 
}
 
static void HandleError(JNIEnv *env)
{
    /*  A simple routine to report and handle an exception.  */
    JobPrint(env, "( C  ) Error occurred on JNI call: ");
    (*env)->ExceptionDescribe(env); /* write exception data to the console */
    (*env)->ExceptionClear(env);    /* clear the exception that was pending */
}
 
static void JobPrint(JNIEnv *env, char *str)
{
    char   *jobStr;
    char   buf[512];
    size_t len;
 
    len = strlen(str);
 
    /*  Only print non-empty string. */
    if (len) {
        jobStr = (len >= 512) ? malloc(len+1) : &buf;
        if (! StringConvert(CONV_UTF2JOB, str, jobStr))
            (*env)->FatalError
              (env,"ERROR in JobPrint: Unable to convert UTF2JOB");
        fprintf(stderr, jobStr);
        if (len >= 512) free(jobStr);
    }
}
 
int StringConvert(int direction, char *sourceStr, char *targetStr)
{
    QtqCode_T source, target;     /* parameters to instantiate iconv  */
    size_t    sStrLen, tStrLen;   /* local copies of string lengths   */
    iconv_t   ourConverter;       /* the actual conversion descriptor */
    int       iconvRC;            /* return code from the conversion  */
    size_t    originalLen;        /* original length of the sourceStr */
 
    /*  Make local copies of the input and output sizes that are initialized
    to the size of the input string. The iconv() requires the
    length parameters to be passed by address (that is as int*).          */
    originalLen = sStrLen = tStrLen = strlen(sourceStr);
 
    /*  Initialize the parameters to the QtqIconvOpen() to zero.  */
    memset(&source,0x00,sizeof(source));
    memset(&target,0x00,sizeof(target));
 
    /*  Depending on direction parameter, set either SOURCE
    or TARGET CCSID to ISO 8859-1 Latin.  */
    if (CONV_UTF2JOB == direction ) {
        source.CCSID = 819; 
    } 
    else {
        target.CCSID = 819;
    }
 
    /*  Create the iconv_t converter object.  */
    ourConverter = QtqIconvOpen(&target,&source);
 
    /*  Make sure that you have a valid converter, otherwise return 0.  */
    if (-1 == ourConverter.return_value) return 0;
 
    /*  Perform the conversion.  */
    iconvRC = iconv(ourConverter,
                    (char**) &sourceStr,
                    &sStrLen,
                    &targetStr,
                    &tStrLen);
 
    /*  If the conversion failed, return a zero.  */
    if (0 != iconvRC ) return 0;
 
    /*  Close the conversion descriptor.  */
    iconv_close(ourConverter);
 
    /*  The targetStr returns pointing to the character just
    past the last converted character, so set the null
    there now.  */
    *targetStr = '\0';
 
    /*  Return the number of characters that were processed. */
    return originalLen-tStrLen;
 
}