diff --git a/src/gen_cpp_Engine.ysl2 b/src/gen_cpp_Engine.ysl2 index c85691d..d952842 100644 --- a/src/gen_cpp_Engine.ysl2 +++ b/src/gen_cpp_Engine.ysl2 @@ -183,6 +183,9 @@ tstylesheet { jobjectArray values = (jobjectArray) env->CallStaticObjectMethod(clazz_«$ljtype», method_values); assert(values); + if (env->ExceptionCheck()) { + return nullptr; // handle exception in Java + } jsize values_size = env->GetArrayLength(values); for (jsize i = 0; i < values_size; i++) { diff --git a/src/jniutils.cc b/src/jniutils.cc index 0af4a49..498e851 100644 --- a/src/jniutils.cc +++ b/src/jniutils.cc @@ -103,7 +103,9 @@ namespace pEp { env->DeleteLocalRef(clazz); - return env->CallIntMethod(obj, method); + jint result = env->CallIntMethod(obj, method); + env->ExceptionCheck(); // handle exception in Java + return result; } jlong callLongMethod( @@ -125,7 +127,9 @@ namespace pEp { env->DeleteLocalRef(clazz); - return env->CallLongMethod(obj, method); + jlong result = env->CallLongMethod(obj, method); + env->ExceptionCheck(); // handle exception in Java + return result; } jobject callObjectMethod( @@ -149,7 +153,9 @@ namespace pEp { env->DeleteLocalRef(clazz); - return env->CallObjectMethod(obj, method, index); + jobject result = env->CallObjectMethod(obj, method, index); + env->ExceptionCheck(); // handle exception in Java + return result; } jboolean callBooleanMethod( @@ -173,7 +179,9 @@ namespace pEp { env->DeleteLocalRef(clazz); - return env->CallBooleanMethod(obj, method, o); + jboolean result = env->CallBooleanMethod(obj, method, o); + env->ExceptionCheck(); // handle exception in Java + return result; } jint outOfMemory(JNIEnv *env) @@ -190,12 +198,12 @@ namespace pEp { { assert(env); jclass clazz = findClass(env, "java/lang/Integer"); + jmethodID constructor = env->GetMethodID(clazz, "", "(I)V"); assert(constructor); + jobject obj = env->NewObject(clazz, constructor, val); assert(obj); - - env->DeleteLocalRef(clazz); return obj; } diff --git a/src/org_pEp_jniadapter_AbstractEngine.cc b/src/org_pEp_jniadapter_AbstractEngine.cc index aa8a2f0..8a454b4 100644 --- a/src/org_pEp_jniadapter_AbstractEngine.cc +++ b/src/org_pEp_jniadapter_AbstractEngine.cc @@ -40,12 +40,20 @@ namespace pEp { JavaVM *jvm= nullptr; std::mutex mutex_obj; - jobject obj = nullptr; + jfieldID field_value = nullptr; jmethodID messageConstructorMethodID = nullptr; jmethodID messageToSendMethodID = nullptr; jmethodID notifyHandShakeMethodID = nullptr; jmethodID needsFastPollMethodID = nullptr; + jmethodID method_values = nullptr; + + jobject obj = nullptr; + + jclass messageClass = nullptr; + jclass identityClass = nullptr;; + jclass signalClass = nullptr; + jclass engineClass = nullptr; class JNISync { public: @@ -59,31 +67,65 @@ namespace pEp { return thread_env; } - virtual void startup_sync() + void startup_sync() { } - virtual void shutdown_sync() + void shutdown_sync() { jvm->DetachCurrentThread(); } } o; + void jni_init() { + JNIEnv *_env = o.env(); + + messageClass = reinterpret_cast( + _env->NewGlobalRef(findClass(_env, "org/pEp/jniadapter/Message"))); + identityClass = reinterpret_cast( + _env->NewGlobalRef(findClass(_env, "org/pEp/jniadapter/_Identity"))); + signalClass = reinterpret_cast( + _env->NewGlobalRef(findClass(_env, "org/pEp/jniadapter/SyncHandshakeSignal"))); + engineClass = reinterpret_cast(_env->NewGlobalRef(findClass(_env, "org/pEp/jniadapter/Engine"))); + + messageConstructorMethodID = _env->GetMethodID(messageClass, "", "(J)V"); + messageToSendMethodID = _env->GetMethodID( + engineClass, + "messageToSendCallFromC", + "(Lorg/pEp/jniadapter/Message;)I"); + needsFastPollMethodID = _env->GetMethodID( + engineClass, + "needsFastPollCallFromC", + "(Z)I"); + notifyHandShakeMethodID = _env->GetMethodID( + engineClass, + "notifyHandshakeCallFromC", + "(Lorg/pEp/jniadapter/_Identity;Lorg/pEp/jniadapter/_Identity;Lorg/pEp/jniadapter/SyncHandshakeSignal;)I"); + + method_values = o.env()->GetStaticMethodID(signalClass, "values", + "()[Lorg/pEp/jniadapter/SyncHandshakeSignal;"); + field_value = o.env()->GetFieldID(signalClass, "value", "I"); + } + PEP_STATUS messageToSend(message *msg) { std::lock_guard l(mutex_obj); debug_log << "\n############### messageToSend() called\n"; jobject msg_ = nullptr; - jint result = 0; - jclass messageClass = reinterpret_cast( - o.env()->NewGlobalRef(findClass(o.env(), "org/pEp/jniadapter/Message"))); + assert(messageClass && messageConstructorMethodID && obj && messageToSendMethodID); + msg_ = o.env()->NewObject(messageClass, messageConstructorMethodID, (jlong) msg); - result = o.env()->CallIntMethod(obj, messageToSendMethodID, msg_); - return (PEP_STATUS) result; + PEP_STATUS status = (PEP_STATUS) o.env()->CallIntMethod(obj, messageToSendMethodID, msg_); + if (o.env()->ExceptionCheck()) { + status = PEP_UNKNOWN_ERROR; + o.env()->ExceptionClear(); + } + + return status; } PEP_STATUS notifyHandshake(pEp_identity *me, pEp_identity *partner, sync_handshake_signal signal) @@ -94,27 +136,21 @@ namespace pEp { jobject me_ = nullptr; jobject partner_ = nullptr; - jclass identityClass = reinterpret_cast( - o.env()->NewGlobalRef(findClass(o.env(), "org/pEp/jniadapter/_Identity"))); - me_ = from_identity(o.env(), me, identityClass); partner_ = from_identity(o.env(), partner, identityClass); jobject signal_ = nullptr; { - jclass signalClass = reinterpret_cast( - o.env()->NewGlobalRef(findClass(o.env(), "org/pEp/jniadapter/SyncHandshakeSignal"))); - assert(signalClass); - jmethodID method_values = o.env()->GetStaticMethodID(signalClass, "values", - "()[Lorg/pEp/jniadapter/SyncHandshakeSignal;"); assert(method_values); - jfieldID field_value = o.env()->GetFieldID(signalClass, "value", "I"); assert(field_value); jobjectArray values = (jobjectArray) o.env()->CallStaticObjectMethod(signalClass, method_values); - assert(values); + if (o.env()->ExceptionCheck()) { + o.env()->ExceptionClear(); + return PEP_UNKNOWN_ERROR; + } jsize values_size = o.env()->GetArrayLength(values); for (jsize i = 0; i < values_size; i++) { @@ -128,9 +164,15 @@ namespace pEp { } } - jint result = o.env()->CallIntMethod(obj, notifyHandShakeMethodID, me_, partner_, signal_); + assert(obj && notifyHandShakeMethodID); + + PEP_STATUS status = (PEP_STATUS) o.env()->CallIntMethod(obj, notifyHandShakeMethodID, me_, partner_, signal_); + if (o.env()->ExceptionCheck()) { + o.env()->ExceptionClear(); + return PEP_UNKNOWN_ERROR; + } - return (PEP_STATUS) result; + return status; } } @@ -142,55 +184,22 @@ extern "C" { jobject me ) { - if (first) + if (first) { env->GetJavaVM(&jvm); - obj = env->NewGlobalRef(me); - jclass _clazz = env->GetObjectClass(obj); - - jclass engineClass = reinterpret_cast(env->NewGlobalRef(findClass(env, "org/pEp/jniadapter/Engine"))); - - if (!messageConstructorMethodID) { - jclass messageClass = reinterpret_cast( - env->NewGlobalRef(findClass(env, "org/pEp/jniadapter/Message"))); - messageConstructorMethodID = env->GetMethodID(messageClass, "", "(J)V"); - } - - if (!messageToSendMethodID) { - messageToSendMethodID = env->GetMethodID( - engineClass, - "messageToSendCallFromC", - "(Lorg/pEp/jniadapter/Message;)I"); - assert(messageToSendMethodID); + jni_init(); + obj = env->NewGlobalRef(me); } - if (!needsFastPollMethodID) { - needsFastPollMethodID = env->GetMethodID( - engineClass, - "needsFastPollCallFromC", - "(Z)I"); - assert(needsFastPollMethodID); - } - - if (!notifyHandShakeMethodID) { - notifyHandShakeMethodID = env->GetMethodID( - engineClass, - "notifyHandshakeCallFromC", - "(Lorg/pEp/jniadapter/_Identity;Lorg/pEp/jniadapter/_Identity;Lorg/pEp/jniadapter/SyncHandshakeSignal;)I"); - assert(notifyHandShakeMethodID); - } - - thread_local static PEP_SESSION _session = nullptr; - PEP_STATUS status = PEP_STATUS_OK; #ifdef DISABLE_SYNC _messageToSend = messageToSend; session(); #else if (first) { - first = false; debug_log << "######## starting sync\n"; startup(messageToSend, notifyHandshake, &o, &JNISync::startup_sync, &JNISync::shutdown_sync); } #endif + first = false; } JNIEXPORT void JNICALL Java_org_pEp_jniadapter_AbstractEngine_release( @@ -198,9 +207,7 @@ extern "C" { jobject me ) { - shutdown(); session(pEp::Adapter::release); - env->DeleteGlobalRef(obj); } int examine_identity(pEp_identity *ident, void *arg) diff --git a/test/Makefile b/test/Makefile index d10c258..9bbdf1e 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,6 +1,6 @@ CLASSPATH=.:../src -#VM=java -Xcheck:jni -Djava.library.path=../src -VM=java -Djava.library.path=../src +VM=java -Xcheck:jni -Djava.library.path=../src +#VM=llvb java -- -Xcheck:jni -Djava.library.path=../src test: Testing.class SyncCallbacks.class HOME=$(PWD) CLASSPATH=$(CLASSPATH) $(VM) Testing diff --git a/test/Testing.java b/test/Testing.java index 835509e..0fea731 100644 --- a/test/Testing.java +++ b/test/Testing.java @@ -2,8 +2,10 @@ import org.pEp.jniadapter.*; import java.util.Vector; import java.net.URL; import java.net.URLClassLoader; -class Testing { +import java.lang.Thread; +import java.lang.InterruptedException; +class Testing { public void printClassPath() { ClassLoader cl = ClassLoader.getSystemClassLoader(); @@ -13,6 +15,7 @@ class Testing { System.out.println(url.getFile()); } } + public static void main(String[] args) { Engine e; @@ -40,7 +43,6 @@ class Testing { System.out.print("Keys generated: "); System.out.println(user.fpr); - // trustwords Identity vb = new Identity(); vb.fpr = "DB4713183660A12ABAFA7714EBE90D44146F62F4"; @@ -77,7 +79,6 @@ class Testing { ex.printStackTrace(); } - System.out.println(enc.getLongmsg()); Vector attachments = enc.getAttachments(); System.out.println(e.toUTF16(attachments.get(1).data)); @@ -103,16 +104,24 @@ class Testing { System.out.println(result.dst.getShortmsg()); System.out.println(result.dst.getLongmsg()); - System.out.println("TEST DONE - FINISHED"); - - try { - e.key_reset(null, null); - } - catch (pEpException ex) { - System.out.println("cannot reset all own keys"); - ex.printStackTrace(); - } - System.exit(0); + System.out.println("TEST DONE - FINISHED"); + + try { + e.key_reset(null, null); + } + catch (pEpException ex) { + System.out.println("cannot reset all own keys"); + ex.printStackTrace(); + } + +// try { +// Thread.sleep(1000); +// } +// catch (InterruptedException ex) { +// +// } + + System.exit(0); }