From bb9f5b749151f38f1c8ebb60f34e9b1a6e94388a Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Thu, 15 Dec 2016 21:24:11 -0800 Subject: [PATCH] jni_util: Add JException wrapper class. This allows more natural C++ Throw semantics (for a variety of string data types) for any java exception that just takes a String argument. --- include/support/jni_util.h | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/include/support/jni_util.h b/include/support/jni_util.h index 39ec6bfbb2..7bfd897844 100644 --- a/include/support/jni_util.h +++ b/include/support/jni_util.h @@ -62,7 +62,7 @@ class JClass { operator jclass() const { return m_cls; } - private: + protected: jclass m_cls = nullptr; }; @@ -570,6 +570,34 @@ std::string GetJavaStackTrace(JNIEnv* env, std::string* func) { return oss.str(); } +// Finds an exception class and keep it as a global reference. +// Similar to JClass, but provides Throw methods. +// Use with caution, as the destructor does NOT call DeleteGlobalRef due +// to potential shutdown issues with doing so. +class JException : public JClass { + public: + JException() = default; + JException(JNIEnv* env, const char* name) : JClass(env, name) { + if (m_cls) + m_constructor = + env->GetMethodID(m_cls, "", "(Ljava/lang/String;)V"); + } + + void Throw(JNIEnv* env, jstring msg) { + jobject exception = env->NewObject(m_cls, m_constructor, msg); + env->Throw(static_cast(exception)); + } + + void Throw(JNIEnv* env, llvm::StringRef msg) { + Throw(env, MakeJString(env, msg)); + } + + explicit operator bool() const { return m_constructor; } + + private: + jmethodID m_constructor = nullptr; +}; + } // namespace java } // namespace wpi