diff options
author | Sven Gothel <[email protected]> | 2020-09-19 00:00:48 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2020-09-19 00:00:48 +0200 |
commit | 5cfe7e13c4dbf07360d928e421050de5e00684a1 (patch) | |
tree | 85226e10b3010de2fc1a0955d2b8ef6f6a9bc6df /java | |
parent | d3d18fc5f276535f958659e04261f936e2d868de (diff) |
helper_base.hpp: Have all raise_java_exception(..) and rethrow_and_raise_java_exception(..) inline, benefitting from __FILE__ and __LINE__
Also have all raise_java_exception(..) call print_exception(..) upfront unconditionally, to not miss any exception
in case a thread has died or the Java caller suppresses the output.
Diffstat (limited to 'java')
-rw-r--r-- | java/jni/helper_base.cxx | 102 | ||||
-rw-r--r-- | java/jni/helper_base.hpp | 135 |
2 files changed, 126 insertions, 111 deletions
diff --git a/java/jni/helper_base.cxx b/java/jni/helper_base.cxx index de85ce2f..ade2aeb5 100644 --- a/java/jni/helper_base.cxx +++ b/java/jni/helper_base.cxx @@ -182,108 +182,25 @@ jobject get_new_arraylist(JNIEnv *env, unsigned int size, jmethodID *add) return result; } -void raise_java_exception(JNIEnv *env, std::exception &e) { - env->ThrowNew(env->FindClass("java/lang/Error"), e.what()); -} -void raise_java_exception(JNIEnv *env, std::runtime_error &e) { - env->ThrowNew(env->FindClass("java/lang/RuntimeException"), e.what()); -} -void raise_java_exception(JNIEnv *env, direct_bt::RuntimeException &e) { - env->ThrowNew(env->FindClass("java/lang/RuntimeException"), e.what()); -} -void raise_java_exception(JNIEnv *env, direct_bt::InternalError &e) { - env->ThrowNew(env->FindClass("java/lang/InternalError"), e.what()); -} -void raise_java_exception(JNIEnv *env, direct_bt::NullPointerException &e) { - env->ThrowNew(env->FindClass("java/lang/NullPointerException"), e.what()); -} -void raise_java_exception(JNIEnv *env, direct_bt::IllegalArgumentException &e) { - env->ThrowNew(env->FindClass("java/lang/IllegalArgumentException"), e.what()); -} -void raise_java_exception(JNIEnv *env, std::invalid_argument &e) { - env->ThrowNew(env->FindClass("java/lang/IllegalArgumentException"), e.what()); -} -void raise_java_exception(JNIEnv *env, direct_bt::IllegalStateException &e) { - env->ThrowNew(env->FindClass("java/lang/IllegalStateException"), e.what()); -} -void raise_java_exception(JNIEnv *env, direct_bt::UnsupportedOperationException &e) { - env->ThrowNew(env->FindClass("java/lang/UnsupportedOperationException"), e.what()); -} -void raise_java_exception(JNIEnv *env, direct_bt::IndexOutOfBoundsException &e) { - env->ThrowNew(env->FindClass("java/lang/IndexOutOfBoundsException"), e.what()); -} -void raise_java_exception(JNIEnv *env, std::bad_alloc &e) { - env->ThrowNew(env->FindClass("java/lang/OutOfMemoryError"), e.what()); -} -void raise_java_exception(JNIEnv *env, direct_bt::BluetoothException &e) { - env->ThrowNew(env->FindClass("org/tinyb/BluetoothException"), e.what()); -} - -void raise_java_runtime_exception(JNIEnv *env, std::runtime_error &e) { - raise_java_exception(env, e); -} -void raise_java_runtime_exception(JNIEnv *env, direct_bt::RuntimeException &e) { - raise_java_exception(env, e); -} -void raise_java_oom_exception(JNIEnv *env, std::bad_alloc &e) { - raise_java_exception(env, e); -} -void raise_java_invalid_arg_exception(JNIEnv *env, std::invalid_argument &e) { - raise_java_exception(env, e); -} -void raise_java_bluetooth_exception(JNIEnv *env, direct_bt::BluetoothException &e) { - raise_java_exception(env, e); -} - -void rethrow_and_raise_java_exception(JNIEnv *env) { - // std::exception_ptr e = std::current_exception(); - try { - // std::rethrow_exception(e); - throw; // re-throw current exception - } catch (std::bad_alloc &e) { \ - raise_java_exception(env, e); - } catch (direct_bt::InternalError &e) { - raise_java_exception(env, e); - } catch (direct_bt::NullPointerException &e) { - raise_java_exception(env, e); - } catch (direct_bt::IllegalArgumentException &e) { - raise_java_exception(env, e); - } catch (direct_bt::IllegalStateException &e) { - raise_java_exception(env, e); - } catch (direct_bt::UnsupportedOperationException &e) { - raise_java_exception(env, e); - } catch (direct_bt::IndexOutOfBoundsException &e) { - raise_java_exception(env, e); - } catch (direct_bt::BluetoothException &e) { - raise_java_exception(env, e); - } catch (direct_bt::RuntimeException &e) { - raise_java_exception(env, e); - } catch (std::runtime_error &e) { - raise_java_exception(env, e); - } catch (std::invalid_argument &e) { - raise_java_exception(env, e); - } catch (std::exception &e) { - raise_java_exception(env, e); - } catch (std::string &msg) { - env->ThrowNew(env->FindClass("java/lang/Error"), msg.c_str()); - } catch (const char *msg) { - env->ThrowNew(env->FindClass("java/lang/Error"), msg); - } catch (...) { - env->ThrowNew(env->FindClass("java/lang/Error"), "Unknown exception type"); - } -} +const std::string unknown_exception_type_msg("Unknown exception type"); bool java_exception_check(JNIEnv *env, const char* file, int line) { jthrowable e = env->ExceptionOccurred(); if( nullptr != e ) { #if 1 - fprintf(stderr, "Java exception occurred @ %s : %d and forwarded.", file, line); fflush(stderr); // ExceptionDescribe prints an exception and a backtrace of the stack to a system error-reporting channel, such as stderr. // The pending exception is cleared as a side-effect of calling this function. This is a convenience routine provided for debugging. env->ExceptionDescribe(); #endif env->ExceptionClear(); // just be sure, to have same side-effects + + jclass eClazz = search_class(env, e); + jmethodID toString = search_method(env, eClazz, "toString", "()Ljava/lang/String;", false); + jstring jmsg = (jstring) env->CallObjectMethod(e, toString); + std::string msg = from_jstring_to_string(env, jmsg); + fprintf(stderr, "Java exception occurred @ %s : %d and forwarded to Java: %s\n", file, line, msg.c_str()); fflush(stderr); + env->Throw(e); // re-throw the java exception - java side! return true; } @@ -294,7 +211,6 @@ void java_exception_check_and_throw(JNIEnv *env, const char* file, int line) { jthrowable e = env->ExceptionOccurred(); if( nullptr != e ) { - fprintf(stderr, "Java exception occurred @ %s : %d and forwarded.", file, line); fflush(stderr); // ExceptionDescribe prints an exception and a backtrace of the stack to a system error-reporting channel, such as stderr. // The pending exception is cleared as a side-effect of calling this function. This is a convenience routine provided for debugging. env->ExceptionDescribe(); @@ -304,6 +220,8 @@ void java_exception_check_and_throw(JNIEnv *env, const char* file, int line) jmethodID toString = search_method(env, eClazz, "toString", "()Ljava/lang/String;", false); jstring jmsg = (jstring) env->CallObjectMethod(e, toString); std::string msg = from_jstring_to_string(env, jmsg); + fprintf(stderr, "Java exception occurred @ %s : %d and forwarded to Native: %s\n", file, line, msg.c_str()); fflush(stderr); + throw direct_bt::RuntimeException("Java exception occurred @ %s : %d: "+msg, file, line); } } diff --git a/java/jni/helper_base.hpp b/java/jni/helper_base.hpp index 0fa56095..9d920f4d 100644 --- a/java/jni/helper_base.hpp +++ b/java/jni/helper_base.hpp @@ -240,29 +240,126 @@ jobject convert_vector_sharedptr_to_jarraylist(JNIEnv *env, std::vector<std::sha return result; } -void raise_java_exception(JNIEnv *env, std::exception &e); -void raise_java_exception(JNIEnv *env, std::runtime_error &e); -void raise_java_exception(JNIEnv *env, direct_bt::RuntimeException &e); -void raise_java_exception(JNIEnv *env, direct_bt::InternalError &e); -void raise_java_exception(JNIEnv *env, direct_bt::NullPointerException &e); -void raise_java_exception(JNIEnv *env, direct_bt::IllegalArgumentException &e); -void raise_java_exception(JNIEnv *env, std::invalid_argument &e); -void raise_java_exception(JNIEnv *env, direct_bt::IllegalStateException &e); -void raise_java_exception(JNIEnv *env, direct_bt::UnsupportedOperationException &e); -void raise_java_exception(JNIEnv *env, direct_bt::IndexOutOfBoundsException &e); -void raise_java_exception(JNIEnv *env, std::bad_alloc &e); -void raise_java_exception(JNIEnv *env, direct_bt::BluetoothException &e); - -void raise_java_runtime_exception(JNIEnv *env, std::runtime_error &e); -void raise_java_runtime_exception(JNIEnv *env, direct_bt::RuntimeException &e); -void raise_java_oom_exception(JNIEnv *env, std::bad_alloc &e); -void raise_java_invalid_arg_exception(JNIEnv *env, std::invalid_argument &e); -void raise_java_bluetooth_exception(JNIEnv *env, direct_bt::BluetoothException &e); +inline void print_exception(const std::exception &e) { + fprintf(stderr, "Native exception occurred @ %s : %d and forwarded to Java: %s\n", __FILE__, __LINE__, e.what()); fflush(stderr); +} +inline void print_exception(const std::string &msg) { + fprintf(stderr, "Native exception occurred @ %s : %d and forwarded to Java: %s\n", __FILE__, __LINE__, msg.c_str()); fflush(stderr); +} +inline void print_exception(const char * cmsg) { + fprintf(stderr, "Native exception occurred @ %s : %d and forwarded to Java: %s\n", __FILE__, __LINE__, cmsg); fflush(stderr); +} + +inline void raise_java_exception(JNIEnv *env, const std::exception &e) { + print_exception(e); + env->ThrowNew(env->FindClass("java/lang/Error"), e.what()); +} +inline void raise_java_exception(JNIEnv *env, const std::runtime_error &e) { + print_exception(e); + env->ThrowNew(env->FindClass("java/lang/RuntimeException"), e.what()); +} +inline void raise_java_exception(JNIEnv *env, const direct_bt::RuntimeException &e) { + print_exception(e); + env->ThrowNew(env->FindClass("java/lang/RuntimeException"), e.what()); +} +inline void raise_java_exception(JNIEnv *env, const direct_bt::InternalError &e) { + print_exception(e); + env->ThrowNew(env->FindClass("java/lang/InternalError"), e.what()); +} +inline void raise_java_exception(JNIEnv *env, const direct_bt::NullPointerException &e) { + print_exception(e); + env->ThrowNew(env->FindClass("java/lang/NullPointerException"), e.what()); +} +inline void raise_java_exception(JNIEnv *env, const direct_bt::IllegalArgumentException &e) { + print_exception(e); + env->ThrowNew(env->FindClass("java/lang/IllegalArgumentException"), e.what()); +} +inline void raise_java_exception(JNIEnv *env, const std::invalid_argument &e) { + print_exception(e); + env->ThrowNew(env->FindClass("java/lang/IllegalArgumentException"), e.what()); +} +inline void raise_java_exception(JNIEnv *env, const direct_bt::IllegalStateException &e) { + print_exception(e); + env->ThrowNew(env->FindClass("java/lang/IllegalStateException"), e.what()); +} +inline void raise_java_exception(JNIEnv *env, const direct_bt::UnsupportedOperationException &e) { + print_exception(e); + env->ThrowNew(env->FindClass("java/lang/UnsupportedOperationException"), e.what()); +} +inline void raise_java_exception(JNIEnv *env, const direct_bt::IndexOutOfBoundsException &e) { + print_exception(e); + env->ThrowNew(env->FindClass("java/lang/IndexOutOfBoundsException"), e.what()); +} +inline void raise_java_exception(JNIEnv *env, const std::bad_alloc &e) { + print_exception(e); + env->ThrowNew(env->FindClass("java/lang/OutOfMemoryError"), e.what()); +} +inline void raise_java_exception(JNIEnv *env, const direct_bt::BluetoothException &e) { + print_exception(e); + env->ThrowNew(env->FindClass("org/tinyb/BluetoothException"), e.what()); +} + +inline void raise_java_runtime_exception(JNIEnv *env, const std::runtime_error &e) { + raise_java_exception(env, e); +} +inline void raise_java_runtime_exception(JNIEnv *env, const direct_bt::RuntimeException &e) { + raise_java_exception(env, e); +} +inline void raise_java_oom_exception(JNIEnv *env, const std::bad_alloc &e) { + raise_java_exception(env, e); +} +inline void raise_java_invalid_arg_exception(JNIEnv *env, const std::invalid_argument &e) { + raise_java_exception(env, e); +} +inline void raise_java_bluetooth_exception(JNIEnv *env, const direct_bt::BluetoothException &e) { + raise_java_exception(env, e); +} + +extern const std::string unknown_exception_type_msg; /** * Re-throw current exception and raise respective java exception * using any matching function above. */ -void rethrow_and_raise_java_exception(JNIEnv *env); +inline void rethrow_and_raise_java_exception(JNIEnv *env) { + // std::exception_ptr e = std::current_exception(); + try { + // std::rethrow_exception(e); + throw; // re-throw current exception + } catch (std::bad_alloc &e) { \ + raise_java_exception(env, e); + } catch (direct_bt::InternalError &e) { + raise_java_exception(env, e); + } catch (direct_bt::NullPointerException &e) { + raise_java_exception(env, e); + } catch (direct_bt::IllegalArgumentException &e) { + raise_java_exception(env, e); + } catch (direct_bt::IllegalStateException &e) { + raise_java_exception(env, e); + } catch (direct_bt::UnsupportedOperationException &e) { + raise_java_exception(env, e); + } catch (direct_bt::IndexOutOfBoundsException &e) { + raise_java_exception(env, e); + } catch (direct_bt::BluetoothException &e) { + raise_java_exception(env, e); + } catch (direct_bt::RuntimeException &e) { + raise_java_exception(env, e); + } catch (std::runtime_error &e) { + raise_java_exception(env, e); + } catch (std::invalid_argument &e) { + raise_java_exception(env, e); + } catch (std::exception &e) { + raise_java_exception(env, e); + } catch (std::string &msg) { + print_exception(msg); + env->ThrowNew(env->FindClass("java/lang/Error"), msg.c_str()); + } catch (const char *msg) { + print_exception(msg); + env->ThrowNew(env->FindClass("java/lang/Error"), msg); + } catch (...) { + print_exception(unknown_exception_type_msg); + env->ThrowNew(env->FindClass("java/lang/Error"), unknown_exception_type_msg.c_str()); + } +} #endif /* HELPER_BASE_HPP_ */ |