aboutsummaryrefslogtreecommitdiffstats
path: root/java
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2020-09-19 02:38:40 +0200
committerSven Gothel <[email protected]>2020-09-19 02:38:40 +0200
commit6971276079dfe45d4dccd847222ee02f4b8cb3d2 (patch)
tree0d5eafb344b695f8d89c6ee3cb6d684252e70703 /java
parenteb8a28236d4479cda60a2b1bd1da919fbee51650 (diff)
C++/JNI: helper_base.hpp/cxx: Rework raise_java_exception(..) and rethrow_and_raise_java_exception[->_impl](..) ..
Commit 5cfe7e13c4dbf07360d928e421050de5e00684a1 intention was noble, however, 'inline' is not guaranteed and doesn't work here. I.e. the desired inline reduction with automatic elision and using __FILE__ and __LINE__ macros is not supported. Instead, move the functions back to helper_base.cxx and add paramter for __FILE__ and __LINE__ to be passed by the only caller macro 'rethrow_and_raise_java_exception(E)'. The latter simply explodes to 'rethrow_and_raise_java_exception_impl((E), __FILE__, __LINE__)', which serves the purposed of having exposed the file and line position where the exceotion got caught. Also support api/tinyb/BluetoothException, rendering commit 3139f93409cac61ba5b80caf506375d94eff8778 valid, i.e. use rethrow_and_raise_java_exception(..) in the tinyb C++/JNI code instead of exploded exception case blocks.
Diffstat (limited to 'java')
-rw-r--r--java/jni/helper_base.cxx112
-rw-r--r--java/jni/helper_base.hpp138
2 files changed, 131 insertions, 119 deletions
diff --git a/java/jni/helper_base.cxx b/java/jni/helper_base.cxx
index ade2aeb..518b28a 100644
--- a/java/jni/helper_base.cxx
+++ b/java/jni/helper_base.cxx
@@ -182,7 +182,113 @@ jobject get_new_arraylist(JNIEnv *env, unsigned int size, jmethodID *add)
return result;
}
-const std::string unknown_exception_type_msg("Unknown exception type");
+static void print_native_caught_exception_fwd2java(const std::exception &e, const char* file, int line) {
+ fprintf(stderr, "Native exception caught @ %s:%d and forward to Java: %s\n", file, line, e.what()); fflush(stderr);
+}
+static void print_native_caught_exception_fwd2java(const std::string &msg, const char* file, int line) {
+ fprintf(stderr, "Native exception caught @ %s:%d and forward to Java: %s\n", file, line, msg.c_str()); fflush(stderr);
+}
+static void print_native_caught_exception_fwd2java(const char * cmsg, const char* file, int line) {
+ fprintf(stderr, "Native exception caught @ %s:%d and forward to Java: %s\n", file, line, cmsg); fflush(stderr);
+}
+
+void raise_java_exception(JNIEnv *env, const std::exception &e, const char* file, int line) {
+ print_native_caught_exception_fwd2java(e, file, line);
+ env->ThrowNew(env->FindClass("java/lang/Error"), e.what());
+}
+void raise_java_exception(JNIEnv *env, const std::runtime_error &e, const char* file, int line) {
+ print_native_caught_exception_fwd2java(e, file, line);
+ env->ThrowNew(env->FindClass("java/lang/RuntimeException"), e.what());
+}
+void raise_java_exception(JNIEnv *env, const direct_bt::RuntimeException &e, const char* file, int line) {
+ print_native_caught_exception_fwd2java(e, file, line);
+ env->ThrowNew(env->FindClass("java/lang/RuntimeException"), e.what());
+}
+void raise_java_exception(JNIEnv *env, const direct_bt::InternalError &e, const char* file, int line) {
+ print_native_caught_exception_fwd2java(e, file, line);
+ env->ThrowNew(env->FindClass("java/lang/InternalError"), e.what());
+}
+void raise_java_exception(JNIEnv *env, const direct_bt::NullPointerException &e, const char* file, int line) {
+ print_native_caught_exception_fwd2java(e, file, line);
+ env->ThrowNew(env->FindClass("java/lang/NullPointerException"), e.what());
+}
+void raise_java_exception(JNIEnv *env, const direct_bt::IllegalArgumentException &e, const char* file, int line) {
+ print_native_caught_exception_fwd2java(e, file, line);
+ env->ThrowNew(env->FindClass("java/lang/IllegalArgumentException"), e.what());
+}
+void raise_java_exception(JNIEnv *env, const std::invalid_argument &e, const char* file, int line) {
+ print_native_caught_exception_fwd2java(e, file, line);
+ env->ThrowNew(env->FindClass("java/lang/IllegalArgumentException"), e.what());
+}
+void raise_java_exception(JNIEnv *env, const direct_bt::IllegalStateException &e, const char* file, int line) {
+ print_native_caught_exception_fwd2java(e, file, line);
+ env->ThrowNew(env->FindClass("java/lang/IllegalStateException"), e.what());
+}
+void raise_java_exception(JNIEnv *env, const direct_bt::UnsupportedOperationException &e, const char* file, int line) {
+ print_native_caught_exception_fwd2java(e, file, line);
+ env->ThrowNew(env->FindClass("java/lang/UnsupportedOperationException"), e.what());
+}
+void raise_java_exception(JNIEnv *env, const direct_bt::IndexOutOfBoundsException &e, const char* file, int line) {
+ print_native_caught_exception_fwd2java(e, file, line);
+ env->ThrowNew(env->FindClass("java/lang/IndexOutOfBoundsException"), e.what());
+}
+void raise_java_exception(JNIEnv *env, const std::bad_alloc &e, const char* file, int line) {
+ print_native_caught_exception_fwd2java(e, file, line);
+ env->ThrowNew(env->FindClass("java/lang/OutOfMemoryError"), e.what());
+}
+void raise_java_exception(JNIEnv *env, const direct_bt::BluetoothException &e, const char* file, int line) {
+ print_native_caught_exception_fwd2java(e, file, line);
+ env->ThrowNew(env->FindClass("org/tinyb/BluetoothException"), e.what());
+}
+void raise_java_exception(JNIEnv *env, const tinyb::BluetoothException &e, const char* file, int line) {
+ print_native_caught_exception_fwd2java(e, file, line);
+ env->ThrowNew(env->FindClass("org/tinyb/BluetoothException"), e.what());
+}
+
+static std::string _unknown_exception_type_msg("Unknown exception type");
+
+void rethrow_and_raise_java_exception_impl(JNIEnv *env, const char* file, int line) {
+ // std::exception_ptr e = std::current_exception();
+ try {
+ // std::rethrow_exception(e);
+ throw; // re-throw current exception
+ } catch (const std::bad_alloc &e) { \
+ raise_java_exception(env, e, file, line);
+ } catch (const direct_bt::InternalError &e) {
+ raise_java_exception(env, e, file, line);
+ } catch (const direct_bt::NullPointerException &e) {
+ raise_java_exception(env, e, file, line);
+ } catch (const direct_bt::IllegalArgumentException &e) {
+ raise_java_exception(env, e, file, line);
+ } catch (const direct_bt::IllegalStateException &e) {
+ raise_java_exception(env, e, file, line);
+ } catch (const direct_bt::UnsupportedOperationException &e) {
+ raise_java_exception(env, e, file, line);
+ } catch (const direct_bt::IndexOutOfBoundsException &e) {
+ raise_java_exception(env, e, file, line);
+ } catch (const direct_bt::BluetoothException &e) {
+ raise_java_exception(env, e, file, line);
+ } catch (const tinyb::BluetoothException &e) {
+ raise_java_exception(env, e, file, line);
+ } catch (const direct_bt::RuntimeException &e) {
+ raise_java_exception(env, e, file, line);
+ } catch (const std::runtime_error &e) {
+ raise_java_exception(env, e, file, line);
+ } catch (const std::invalid_argument &e) {
+ raise_java_exception(env, e, file, line);
+ } catch (const std::exception &e) {
+ raise_java_exception(env, e, file, line);
+ } catch (const std::string &msg) {
+ print_native_caught_exception_fwd2java(msg, file, line);
+ env->ThrowNew(env->FindClass("java/lang/Error"), msg.c_str());
+ } catch (const char *msg) {
+ print_native_caught_exception_fwd2java(msg, file, line);
+ env->ThrowNew(env->FindClass("java/lang/Error"), msg);
+ } catch (...) {
+ print_native_caught_exception_fwd2java(_unknown_exception_type_msg, file, line);
+ env->ThrowNew(env->FindClass("java/lang/Error"), _unknown_exception_type_msg.c_str());
+ }
+}
bool java_exception_check(JNIEnv *env, const char* file, int line)
{
@@ -199,7 +305,7 @@ bool java_exception_check(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 Java: %s\n", file, line, msg.c_str()); fflush(stderr);
+ fprintf(stderr, "Java exception occurred @ %s:%d and forward to Java: %s\n", file, line, msg.c_str()); fflush(stderr);
env->Throw(e); // re-throw the java exception - java side!
return true;
@@ -220,7 +326,7 @@ 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);
+ fprintf(stderr, "Java exception occurred @ %s:%d and forward 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 9d920f4..4537240 100644
--- a/java/jni/helper_base.hpp
+++ b/java/jni/helper_base.hpp
@@ -34,7 +34,8 @@
#include <functional>
#include <jni.h>
-#include "BasicTypes.hpp"
+#include "direct_bt/BasicTypes.hpp"
+#include "tinyb/BluetoothException.hpp"
/**
* Return true if a java exception occurred, otherwise false.
@@ -240,126 +241,31 @@ jobject convert_vector_sharedptr_to_jarraylist(JNIEnv *env, std::vector<std::sha
return result;
}
-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);
-}
+void raise_java_exception(JNIEnv *env, const std::exception &e, const char* file, int line);
+void raise_java_exception(JNIEnv *env, const std::runtime_error &e, const char* file, int line);
+void raise_java_exception(JNIEnv *env, const direct_bt::RuntimeException &e, const char* file, int line);
+void raise_java_exception(JNIEnv *env, const direct_bt::InternalError &e, const char* file, int line);
+void raise_java_exception(JNIEnv *env, const direct_bt::NullPointerException &e, const char* file, int line);
+void raise_java_exception(JNIEnv *env, const direct_bt::IllegalArgumentException &e, const char* file, int line);
+void raise_java_exception(JNIEnv *env, const std::invalid_argument &e, const char* file, int line);
+void raise_java_exception(JNIEnv *env, const direct_bt::IllegalStateException &e, const char* file, int line);
+void raise_java_exception(JNIEnv *env, const direct_bt::UnsupportedOperationException &e, const char* file, int line);
+void raise_java_exception(JNIEnv *env, const direct_bt::IndexOutOfBoundsException &e, const char* file, int line);
+void raise_java_exception(JNIEnv *env, const std::bad_alloc &e, const char* file, int line);
+void raise_java_exception(JNIEnv *env, const direct_bt::BluetoothException &e, const char* file, int line);
+void raise_java_exception(JNIEnv *env, const tinyb::BluetoothException &e, const char* file, int line);
-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_impl(JNIEnv *env, const char* file, int line);
/**
* Re-throw current exception and raise respective java exception
* using any matching function above.
*/
-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());
- }
-}
+#define rethrow_and_raise_java_exception(E) rethrow_and_raise_java_exception_impl((E), __FILE__, __LINE__)
+// inline void rethrow_and_raise_java_exception(JNIEnv *env) { rethrow_and_raise_java_exception_impl(env, __FILE__, __LINE__); }
#endif /* HELPER_BASE_HPP_ */