Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/share/jni/ExceptionCheckingJniEnv.hpp
41161 views
/*1* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.2* Copyright (c) 2018, 2019, Google 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 it6* under the terms of the GNU General Public License version 2 only, as7* published by the Free Software Foundation.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 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 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*/23#ifndef NSK_EXCEPTIONCHECKINGJNIENV_DEFINED24#define NSK_EXCEPTIONCHECKINGJNIENV_DEFINED2526#include <jni.h>2728/**29* ExceptionCheckingJniEnv wraps around the JNIEnv data structure and30* methods to enable automatic exception checking. This allows test writers31* and readers to concentrate on what the test is to do and leave the32* error checking and throwing to this data structure and subsystem.33*34* For example:35*36* ... JNIEnv* env ...37* jclass klass = env->GetObjectClass(o);38* if (klass == NULL) {39* printf("Error: GetObjectClass returned NULL\n");40* return;41* }42* if (env->ExceptionCheck()) {43* ...44* }45*46* Can be simplified to:47* ... ExceptionCheckingJniEnv* env ...48* jclass klass = env->GetObjectClass(o, TRACE_JNI_CALL);49*50* Where now the JNI Exception checking and the NULL return checking are done51* internally and will perform whatever action the ErrorHandler requires.52*53* Note the TRACE_JNI_CALL parameter that allows to trace where the call is54* happening from for debugging.55*56* By default, the error handler describes the exception via the JNI57* ExceptionDescribe method and calls FatalError.58*/5960#define TRACE_JNI_CALL __LINE__, __FILE__61#define TRACE_JNI_CALL_VARARGS(...) __LINE__, __FILE__, __VA_ARGS__6263class ExceptionCheckingJniEnv {64public:65// JNIEnv API redefinitions.66jclass FindClass(const char *name, int line, const char* file_name);6768jfieldID GetStaticFieldID(jclass klass, const char* name, const char* type,69int line, const char* file_name);70jfieldID GetFieldID(jclass klass, const char* name, const char* type,71int line, const char* file_name);72jmethodID GetStaticMethodID(jclass klass, const char* name, const char* sig,73int line, const char* file_name);74jmethodID GetMethodID(jclass klass, const char* name, const char* sig,75int line, const char* file_name);7677jclass GetObjectClass(jobject obj, int line, const char* file_name);78jobject GetObjectField(jobject obj, jfieldID field, int line, const char* file_name);79jobject GetStaticObjectField(jclass kls, jfieldID field, int line, const char* file_name);80void SetObjectField(jobject obj, jfieldID field, jobject value,81int line, const char* file_name);8283jsize GetArrayLength(jarray array, int line, const char* file_name);84jsize GetStringLength(jstring str, int line, const char* file_name);8586void* GetPrimitiveArrayCritical(jarray array, jboolean* isCopy,87int line, const char* file_name);88void ReleasePrimitiveArrayCritical(jarray array, void* carray, jint mode,89int line, const char* file_name);90const jchar* GetStringCritical(jstring str, jboolean* isCopy,91int line, const char* file_name);92void ReleaseStringCritical(jstring str, const jchar* carray,93int line, const char* file_name);9495jbyte* GetByteArrayElements(jbyteArray array, jboolean* isCopy,96int line, const char* file_name);97void ReleaseByteArrayElements(jbyteArray array, jbyte* byte_array, jint mode,98int line, const char* file_name);99jint RegisterNatives(jclass clazz, const JNINativeMethod *methods, jint nMethods,100int line, const char* file_name);101102jobject NewObject(jclass kls, jmethodID methodID,103int line, const char* file_name, ...);104jobject NewGlobalRef(jobject obj, int line, const char* file_name);105void DeleteGlobalRef(jobject obj, int line, const char* file_name);106jobject NewLocalRef(jobject ref, int line, const char* file_name);107void DeleteLocalRef(jobject ref, int line, const char* file_name);108jweak NewWeakGlobalRef(jobject obj, int line, const char* file_name);109void DeleteWeakGlobalRef(jweak obj, int line, const char* file_name);110111jboolean IsSameObject(jobject ref1, jobject ref2, int line,112const char* file_name);113114jobject CallObjectMethod(jobject obj, jmethodID methodID, int line,115const char* file_name, ...);116void CallVoidMethod(jobject obj, jmethodID methodID, int line,117const char* file_name, ...);118119// ExceptionCheckingJniEnv methods.120JNIEnv* GetJNIEnv() {121return _jni_env;122}123124void HandleError(const char* msg) {125if (_error_handler) {126_error_handler(_jni_env, msg);127}128}129130typedef void (*ErrorHandler)(JNIEnv* env, const char* error_message);131132static void FatalError(JNIEnv* env, const char* message) {133if (env->ExceptionCheck()) {134env->ExceptionDescribe();135}136env->FatalError(message);137}138139ExceptionCheckingJniEnv(JNIEnv* jni_env, ErrorHandler error_handler) :140_jni_env(jni_env), _error_handler(error_handler) {}141142private:143JNIEnv* _jni_env;144ErrorHandler _error_handler;145};146147// We cannot use unique_ptr due to this being gnu98++, so use this instead:148class ExceptionCheckingJniEnvPtr {149private:150ExceptionCheckingJniEnv _env;151152public:153ExceptionCheckingJniEnv* operator->() {154return &_env;155}156157ExceptionCheckingJniEnvPtr(158JNIEnv* jni_env,159ExceptionCheckingJniEnv::ErrorHandler error_handler = ExceptionCheckingJniEnv::FatalError) :160_env(jni_env, error_handler) {161}162};163164#endif165166167