From ce7611562f6e89773f6f9c6cea7e6de963b1fe89 Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Wed, 14 Dec 2016 23:16:09 -0800 Subject: [PATCH] Make JClass more useful and use it in ntcore JNI. --- java/lib/NetworkTablesJNI.cpp | 68 +++++++++++------------------- wpiutil/include/support/jni_util.h | 8 ++-- 2 files changed, 29 insertions(+), 47 deletions(-) diff --git a/java/lib/NetworkTablesJNI.cpp b/java/lib/NetworkTablesJNI.cpp index 03c77eb..1dd91f9 100644 --- a/java/lib/NetworkTablesJNI.cpp +++ b/java/lib/NetworkTablesJNI.cpp @@ -24,13 +24,13 @@ using namespace wpi::java; // Used for callback. static JavaVM *jvm = nullptr; -static jclass booleanCls = nullptr; -static jclass doubleCls = nullptr; -static jclass connectionInfoCls = nullptr; -static jclass entryInfoCls = nullptr; -static jclass keyNotDefinedEx = nullptr; -static jclass persistentEx = nullptr; -static jclass illegalArgEx = nullptr; +static JClass booleanCls; +static JClass doubleCls; +static JClass connectionInfoCls; +static JClass entryInfoCls; +static JClass keyNotDefinedEx; +static JClass persistentEx; +static JClass illegalArgEx; // Thread-attached environment for listener callbacks. static JNIEnv *listenerEnv = nullptr; @@ -64,49 +64,29 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { return JNI_ERR; // Cache references to classes - jclass local; - - local = env->FindClass("java/lang/Boolean"); - if (!local) return JNI_ERR; - booleanCls = static_cast(env->NewGlobalRef(local)); + booleanCls = JClass(env, "java/lang/Boolean"); if (!booleanCls) return JNI_ERR; - env->DeleteLocalRef(local); - local = env->FindClass("java/lang/Double"); - if (!local) return JNI_ERR; - doubleCls = static_cast(env->NewGlobalRef(local)); + doubleCls = JClass(env, "java/lang/Double"); if (!doubleCls) return JNI_ERR; - env->DeleteLocalRef(local); - local = env->FindClass("edu/wpi/first/wpilibj/networktables/ConnectionInfo"); - if (!local) return JNI_ERR; - connectionInfoCls = static_cast(env->NewGlobalRef(local)); + connectionInfoCls = + JClass(env, "edu/wpi/first/wpilibj/networktables/ConnectionInfo"); if (!connectionInfoCls) return JNI_ERR; - env->DeleteLocalRef(local); - local = env->FindClass("edu/wpi/first/wpilibj/networktables/EntryInfo"); - if (!local) return JNI_ERR; - entryInfoCls = static_cast(env->NewGlobalRef(local)); + entryInfoCls = JClass(env, "edu/wpi/first/wpilibj/networktables/EntryInfo"); if (!entryInfoCls) return JNI_ERR; - env->DeleteLocalRef(local); - local = - env->FindClass("edu/wpi/first/wpilibj/networktables/NetworkTableKeyNotDefined"); - keyNotDefinedEx = static_cast(env->NewGlobalRef(local)); + keyNotDefinedEx = JClass( + env, "edu/wpi/first/wpilibj/networktables/NetworkTableKeyNotDefined"); if (!keyNotDefinedEx) return JNI_ERR; - env->DeleteLocalRef(local); - local = - env->FindClass("edu/wpi/first/wpilibj/networktables/PersistentException"); - persistentEx = static_cast(env->NewGlobalRef(local)); + persistentEx = + JClass(env, "edu/wpi/first/wpilibj/networktables/PersistentException"); if (!persistentEx) return JNI_ERR; - env->DeleteLocalRef(local); - local = env->FindClass("java/lang/IllegalArgumentException"); - if (!local) return JNI_ERR; - illegalArgEx = static_cast(env->NewGlobalRef(local)); + illegalArgEx = JClass(env, "java/lang/IllegalArgumentException"); if (!illegalArgEx) return JNI_ERR; - env->DeleteLocalRef(local); // Initial configuration of listener start/exit nt::SetListenerOnStart(ListenerOnStart); @@ -120,13 +100,13 @@ JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) { if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6) != JNI_OK) return; // Delete global references - if (booleanCls) env->DeleteGlobalRef(booleanCls); - if (doubleCls) env->DeleteGlobalRef(doubleCls); - if (connectionInfoCls) env->DeleteGlobalRef(connectionInfoCls); - if (entryInfoCls) env->DeleteGlobalRef(entryInfoCls); - if (keyNotDefinedEx) env->DeleteGlobalRef(keyNotDefinedEx); - if (persistentEx) env->DeleteGlobalRef(persistentEx); - if (illegalArgEx) env->DeleteGlobalRef(illegalArgEx); + booleanCls.free(env); + doubleCls.free(env); + connectionInfoCls.free(env); + entryInfoCls.free(env); + keyNotDefinedEx.free(env); + persistentEx.free(env); + illegalArgEx.free(env); jvm = nullptr; } diff --git a/wpiutil/include/support/jni_util.h b/wpiutil/include/support/jni_util.h index 2564c13..7659abd 100644 --- a/wpiutil/include/support/jni_util.h +++ b/wpiutil/include/support/jni_util.h @@ -32,7 +32,9 @@ namespace java { // to potential shutdown issues with doing so. class JClass { public: - JClass(JNIEnv* env, const char* name) : m_cls(nullptr) { + JClass() = default; + + JClass(JNIEnv* env, const char* name) { jclass local = env->FindClass(name); if (!local) return; m_cls = static_cast(env->NewGlobalRef(local)); @@ -40,7 +42,7 @@ class JClass { } void free(JNIEnv *env) { - env->DeleteGlobalRef(m_cls); + if (m_cls) env->DeleteGlobalRef(m_cls); m_cls = nullptr; } @@ -49,7 +51,7 @@ class JClass { operator jclass() const { return m_cls; } private: - jclass m_cls; + jclass m_cls = nullptr; }; // Container class for cleaning up Java local references.