1 /*
2  * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 #include <jni.h>
25 
26 static jmethodID _callable_method_id;
27 static jmethodID _callable_nested_method_id;
28 
check_exceptions(JNIEnv * env)29 static void check_exceptions(JNIEnv *env) {
30   if ((*env)->ExceptionCheck(env)) {
31     (*env)->ExceptionDescribe(env);
32     (*env)->FatalError(env, "Unexpected Exception");
33   }
34 }
35 
get_method_id(JNIEnv * env,jclass clz,jstring jname,jstring jsig)36 static jmethodID get_method_id(JNIEnv *env, jclass clz, jstring jname, jstring jsig) {
37   jmethodID mid;
38   const char *name, *sig;
39 
40   name = (*env)->GetStringUTFChars(env, jname, NULL);
41   check_exceptions(env);
42 
43   sig  = (*env)->GetStringUTFChars(env, jsig, NULL);
44   check_exceptions(env);
45 
46   mid  = (*env)->GetMethodID(env, clz, name, sig);
47   check_exceptions(env);
48 
49   (*env)->ReleaseStringUTFChars(env, jname, name);
50   (*env)->ReleaseStringUTFChars(env, jsig, sig);
51   return mid;
52 }
53 
54 JNIEXPORT void JNICALL
Java_TestCheckedJniExceptionCheck_initMethodIds(JNIEnv * env,jobject obj,jstring callable_method_name,jstring callable_method_sig,jstring callable_nested_method_name,jstring callable_nested_method_sig)55 Java_TestCheckedJniExceptionCheck_initMethodIds(JNIEnv *env,
56                                                 jobject obj,
57                                                 jstring callable_method_name,
58                                                 jstring callable_method_sig,
59                                                 jstring callable_nested_method_name,
60                                                 jstring callable_nested_method_sig) {
61   jclass clz = (*env)->GetObjectClass(env, obj);
62 
63   _callable_method_id = get_method_id(env, clz,
64                                       callable_method_name,
65                                       callable_method_sig);
66 
67   _callable_nested_method_id = get_method_id(env, clz,
68                                              callable_nested_method_name,
69                                              callable_nested_method_sig);
70 }
71 
72 JNIEXPORT void JNICALL
Java_TestCheckedJniExceptionCheck_callJavaFromNative(JNIEnv * env,jobject obj,jint nofCalls,jboolean checkExceptions)73 Java_TestCheckedJniExceptionCheck_callJavaFromNative(JNIEnv *env,
74                                                      jobject obj,
75                                                      jint nofCalls,
76                                                      jboolean checkExceptions) {
77   int i;
78   for (i = 0; i < nofCalls; i++) {
79     (*env)->CallVoidMethod(env, obj, _callable_method_id);
80     if (checkExceptions == JNI_TRUE) {
81       check_exceptions(env);
82     }
83   }
84 }
85 
86 JNIEXPORT void JNICALL
Java_TestCheckedJniExceptionCheck_callNestedJavaFromNative(JNIEnv * env,jobject obj,jint nofCalls,jboolean checkExceptions)87 Java_TestCheckedJniExceptionCheck_callNestedJavaFromNative(JNIEnv *env,
88                                                            jobject obj,
89                                                            jint nofCalls,
90                                                            jboolean checkExceptions) {
91   int i;
92   for (i = 0; i < nofCalls; i++) {
93     (*env)->CallVoidMethod(env, obj, _callable_nested_method_id, nofCalls, checkExceptions);
94     if (checkExceptions == JNI_TRUE) {
95       check_exceptions(env);
96     }
97   }
98 }
99