FatalError
void
FatalError
(JNIEnv *env, const char *msg);
Raises a fatal error and does not expect the VM to recover. This function does not return.
LINKAGE:
Index 18 in the JNIEnv interface function table.
PARAMETERS:
env
: the JNI interface pointer.msg
: an error message. The string is encoded in modified UTF-8.#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. */
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. FatalError */
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. */
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. FatalError */
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; }