diff options
author | Sven Gothel <[email protected]> | 2020-04-21 13:05:53 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2020-04-21 13:05:53 +0200 |
commit | 2bacdad45d6c7a315937c4c3723fba54fb83b631 (patch) | |
tree | 912cc4c8440a00aee8ab5cbe8a8c1d5c6e07a2cb /java/jni/helper_base.cxx | |
parent | d123b2363692d4e95340aa63bf5246cd293b4f30 (diff) |
Refine: DBT API, HCISession/DBTAdapter lifecycle, API doc and C++ and C++/JNI exception handling
- HCISession: Handle multiple connections
- DBTDevice holds le_conn_handle and provides the le_disconnect as well
- HCISession maintains a vector of connected devices
- HCISession/DBTAdapter: Cleanup shutdown and refine lifecycle
- DBTDevice/DBTAdapter: Drop explicit HCISession argument,
simply use the attached HCISession of DBTAdapter.
- Refine API doc in general
+++
- Device Java/JNI: Add a few more methods to test connect/disconnect.
+++
Refine C++ and C++/JNI exception handling:
- Use new java_exception_check_and_throw(..):
Throw C++ exception on pending Java exception, retrieving toString() message.
- Use new java_exception_check(..):
Return immediately from JNI on pending Java exception.
- Replace macro CATCH_EXCEPTION_AND_RAISE_JAVA(..)
with new rethrow_and_raise_java_exception(..), re-trhowing exception
and raising detailed Java exception.
Diffstat (limited to 'java/jni/helper_base.cxx')
-rw-r--r-- | java/jni/helper_base.cxx | 65 |
1 files changed, 59 insertions, 6 deletions
diff --git a/java/jni/helper_base.cxx b/java/jni/helper_base.cxx index dd3dcf54..c72de97f 100644 --- a/java/jni/helper_base.cxx +++ b/java/jni/helper_base.cxx @@ -31,6 +31,9 @@ #include <stdexcept> #include <vector> +#define VERBOSE_ON 1 +#include <dbt_debug.hpp> + #include "helper_base.hpp" #define JAVA_MAIN_PACKAGE "org/tinyb" @@ -208,13 +211,63 @@ void raise_java_bluetooth_exception(JNIEnv *env, direct_bt::BluetoothException & env->ThrowNew(env->FindClass("org/tinyb/BluetoothException"), e.what()); } -void exception_check_raise_and_throw(JNIEnv *env, const char* file, int line) +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_oom_exception(env, e); + } catch (direct_bt::BluetoothException &e) { + raise_java_bluetooth_exception(env, e); + } catch (direct_bt::RuntimeException &e) { + raise_java_runtime_exception(env, e); + } catch (std::runtime_error &e) { + raise_java_runtime_exception(env, e); + } catch (std::invalid_argument &e) { + raise_java_invalid_arg_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"); + } +} + +bool java_exception_check(JNIEnv *env, const char* file, int line) +{ + jthrowable e = env->ExceptionOccurred(); + if( nullptr != e ) { +#ifdef VERBOSE_ON + DBG_PRINT("Java exception occurred @ %s : %d and forwarded.", file, line); + // 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 /* VERBOSE_ON */ + env->ExceptionClear(); // just be sure, to have same side-effects + env->Throw(e); // re-throw the java exception - java side! + return true; + } + return false; +} + +void java_exception_check_and_throw(JNIEnv *env, const char* file, int line) { - if( env->ExceptionCheck() ) { + jthrowable e = env->ExceptionOccurred(); + if( nullptr != e ) { + ERR_PRINT("Java exception occurred @ %s : %d and forwarded.", file, line); + // 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(); - jthrowable e = env->ExceptionOccurred(); - env->ExceptionClear(); - env->Throw(e); - throw direct_bt::RuntimeException("Java exception occurred and forwarded.", file, line); + 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); + throw direct_bt::RuntimeException("Java exception occurred @ %s : %d: "+msg, file, line); } } |