29 /**
30 * ExceptionCheckingJniEnv wraps around the JNIEnv data structure and
31 * methods to enable automatic exception checking. This allows test writers
32 * and readers to concentrate on what the test is to do and leave the
33 * error checking and throwing to this data structure and subsystem.
34 *
35 * For example:
36 *
37 * ... JNIEnv* env ...
38 * jclass klass = env->GetObjectClass(o);
39 * if (klass == NULL) {
40 * printf("Error: GetObjectClass returned NULL\n");
41 * return;
42 * }
43 * if (env->ExceptionCheck()) {
44 * ...
45 * }
46 *
47 * Can be simplified to:
48 * ... ExceptionCheckingJniEnv* env ...
49 * jclass klass = env->GetObjectClass(o);
50 *
51 * Where now the JNI Exception checking and the NULL return checking are done
52 * internally and will perform whatever action the ErrorHandler requires.
53 *
54 * By default, the error handler describes the exception via the JNI
55 * ExceptionDescribe method and calls FatalError.
56 *
57 * Note: at a future date, this will also include the tracing mechanism done in
58 * NSK_VERIFY, which will thus embed its logic into the ExceptionCheckingJniEnv
59 * and clearing that up for the code readers and writers.
60 */
61 class ExceptionCheckingJniEnv {
62 public:
63 // JNIEnv API redefinitions.
64 jfieldID GetFieldID(jclass klass, const char *name, const char* type);
65 jclass GetObjectClass(jobject obj);
66 jobject GetObjectField(jobject obj, jfieldID field);
67 void SetObjectField(jobject obj, jfieldID field, jobject value);
68
69 jsize GetArrayLength(jarray array);
70 jsize GetStringLength(jstring str);
71
72 void* GetPrimitiveArrayCritical(jarray array, jboolean* isCopy);
73 void ReleasePrimitiveArrayCritical(jarray array, void* carray, jint mode);
74 const jchar* GetStringCritical(jstring str, jboolean* isCopy);
75 void ReleaseStringCritical(jstring str, const jchar* carray);
76
77 jobject NewGlobalRef(jobject obj);
78 void DeleteGlobalRef(jobject obj);
79 jobject NewLocalRef(jobject ref);
80 void DeleteLocalRef(jobject ref);
81 jweak NewWeakGlobalRef(jobject obj);
82 void DeleteWeakGlobalRef(jweak obj);
83
84 // ExceptionCheckingJniEnv methods.
85 JNIEnv* GetJNIEnv() {
86 return _jni_env;
87 }
88
89 void HandleError(const char* msg) {
90 if (_error_handler) {
91 _error_handler(_jni_env, msg);
92 }
93 }
94
95 typedef void (*ErrorHandler)(JNIEnv* env, const char* error_message);
96
97 static void FatalError(JNIEnv* env, const char* message) {
98 if (env->ExceptionCheck()) {
99 env->ExceptionDescribe();
100 }
101 env->FatalError(message);
102 }
103
104 ExceptionCheckingJniEnv(JNIEnv* jni_env, ErrorHandler error_handler) :
105 _jni_env(jni_env), _error_handler(error_handler) {}
106
107 private:
108 JNIEnv* _jni_env;
109 ErrorHandler _error_handler;
110 };
111
112 // We cannot use unique_ptr due to this being gnu98++, so use this instead:
113 class ExceptionCheckingJniEnvPtr {
114 private:
115 ExceptionCheckingJniEnv _env;
116
117 public:
118 ExceptionCheckingJniEnv* operator->() {
119 return &_env;
120 }
121
|
29 /**
30 * ExceptionCheckingJniEnv wraps around the JNIEnv data structure and
31 * methods to enable automatic exception checking. This allows test writers
32 * and readers to concentrate on what the test is to do and leave the
33 * error checking and throwing to this data structure and subsystem.
34 *
35 * For example:
36 *
37 * ... JNIEnv* env ...
38 * jclass klass = env->GetObjectClass(o);
39 * if (klass == NULL) {
40 * printf("Error: GetObjectClass returned NULL\n");
41 * return;
42 * }
43 * if (env->ExceptionCheck()) {
44 * ...
45 * }
46 *
47 * Can be simplified to:
48 * ... ExceptionCheckingJniEnv* env ...
49 * jclass klass = env->GetObjectClass(o, TRACE_JNI_CALL);
50 *
51 * Where now the JNI Exception checking and the NULL return checking are done
52 * internally and will perform whatever action the ErrorHandler requires.
53 *
54 * Note the TRACE_JNI_CALL parameter that allows to trace where the call is
55 * happening from for debugging.
56 *
57 * By default, the error handler describes the exception via the JNI
58 * ExceptionDescribe method and calls FatalError.
59 */
60
61 #define TRACE_JNI_CALL __LINE__, __FILE__
62
63 class ExceptionCheckingJniEnv {
64 public:
65 // JNIEnv API redefinitions.
66 jclass FindClass(const char *name, int line, const char* file_name);
67
68 jfieldID GetStaticFieldID(jclass klass, const char* name, const char* type,
69 int line, const char* file_name);
70 jfieldID GetFieldID(jclass klass, const char* name, const char* type,
71 int line, const char* file_name);
72 jmethodID GetMethodID(jclass klass, const char* name, const char* sig,
73 int line, const char* file_name);
74
75 jclass GetObjectClass(jobject obj, int line, const char* file_name);
76 jobject GetObjectField(jobject obj, jfieldID field, int line, const char* file_name);
77 jobject GetStaticObjectField(jclass kls, jfieldID field, int line, const char* file_name);
78 void SetObjectField(jobject obj, jfieldID field, jobject value,
79 int line, const char* file_name);
80
81 jsize GetArrayLength(jarray array, int line, const char* file_name);
82 jsize GetStringLength(jstring str, int line, const char* file_name);
83
84 void* GetPrimitiveArrayCritical(jarray array, jboolean* isCopy,
85 int line, const char* file_name);
86 void ReleasePrimitiveArrayCritical(jarray array, void* carray, jint mode,
87 int line, const char* file_name);
88 const jchar* GetStringCritical(jstring str, jboolean* isCopy,
89 int line, const char* file_name);
90 void ReleaseStringCritical(jstring str, const jchar* carray,
91 int line, const char* file_name);
92
93 jbyte* GetByteArrayElements(jbyteArray array, jboolean* isCopy,
94 int line, const char* file_name);
95 void ReleaseByteArrayElements(jbyteArray array, jbyte* byte_array, jint mode,
96 int line, const char* file_name);
97 jint RegisterNatives(jclass clazz, const JNINativeMethod *methods, jint nMethods,
98 int line, const char* file_name);
99
100 jobject NewObject(jclass kls, jmethodID methodID,
101 int line, const char* file_name, ...);
102 jobject NewGlobalRef(jobject obj, int line, const char* file_name);
103 void DeleteGlobalRef(jobject obj, int line, const char* file_name);
104 jobject NewLocalRef(jobject ref, int line, const char* file_name);
105 void DeleteLocalRef(jobject ref, int line, const char* file_name);
106 jweak NewWeakGlobalRef(jobject obj, int line, const char* file_name);
107 void DeleteWeakGlobalRef(jweak obj, int line, const char* file_name);
108
109 // ExceptionCheckingJniEnv methods.
110 JNIEnv* GetJNIEnv() {
111 return _jni_env;
112 }
113
114 void HandleError(const char* msg) {
115 if (_error_handler) {
116 _error_handler(_jni_env, msg);
117 }
118 }
119
120 typedef void (*ErrorHandler)(JNIEnv* env, const char* error_message);
121
122 static void FatalError(JNIEnv* env, const char* message) {
123 if (env->ExceptionCheck()) {
124 env->ExceptionDescribe();
125 }
126 env->FatalError(message);
127 }
128
129 static void NonFatalError(JNIEnv* env, const char* message) {
130 if (env->ExceptionCheck()) {
131 env->ExceptionDescribe();
132 }
133 printf("%s", message);
134 }
135
136 ExceptionCheckingJniEnv(JNIEnv* jni_env, ErrorHandler error_handler) :
137 _jni_env(jni_env), _error_handler(error_handler) {}
138
139 private:
140 JNIEnv* _jni_env;
141 ErrorHandler _error_handler;
142 };
143
144 // We cannot use unique_ptr due to this being gnu98++, so use this instead:
145 class ExceptionCheckingJniEnvPtr {
146 private:
147 ExceptionCheckingJniEnv _env;
148
149 public:
150 ExceptionCheckingJniEnv* operator->() {
151 return &_env;
152 }
153
|