diff --git a/plugin/oji/MRJCarbon/plugin/Source/CSecureEnv.cpp b/plugin/oji/MRJCarbon/plugin/Source/CSecureEnv.cpp index 3835509c7f5..21513dd48be 100644 --- a/plugin/oji/MRJCarbon/plugin/Source/CSecureEnv.cpp +++ b/plugin/oji/MRJCarbon/plugin/Source/CSecureEnv.cpp @@ -152,6 +152,7 @@ static void netscape_oji_JNIThread_run(JNIEnv* env, jobject self) JavaMessage* msg = requests.getMessage(); if (msg != NULL) { msg->execute(env); + secureEnv->savePendingException(env); replies.putMessage(msg); replies.notify(); } else { @@ -354,7 +355,7 @@ CSecureEnv::CSecureEnv(MRJPlugin* plugin, JNIEnv* proxyEnv, JNIEnv* javaEnv) : SupportsMixin(this, sInterfaces, kInterfaceCount), mPlugin(plugin), mProxyEnv(proxyEnv), mJavaEnv(javaEnv), mSession(plugin->getSession()), mThreadManager(plugin->getThreadManager()), - mIsRunning(NULL), mJavaQueue(NULL), mNativeQueue(NULL) + mIsRunning(NULL), mJavaQueue(NULL), mNativeQueue(NULL), mPendingException(NULL) { // need to create the JNIThread for communicating with Java. if (mJavaEnv != NULL) @@ -1451,16 +1452,18 @@ NS_IMETHODIMP CSecureEnv::ThrowNew(/*[in]*/ jclass clazz, class ExceptionOccurredMessage : public JavaMessage { + CSecureEnv* secureEnv; jthrowable* result; public: - ExceptionOccurredMessage(jthrowable* result) + ExceptionOccurredMessage(CSecureEnv* secureEnv, jthrowable* result) { + this->secureEnv = secureEnv; this->result = result; } virtual void execute(JNIEnv* env) { - *result = env->ExceptionOccurred(); + *result = secureEnv->getPendingException(env); } }; @@ -1469,8 +1472,8 @@ NS_IMETHODIMP CSecureEnv::ExceptionOccurred(/*[out]*/ jthrowable* result) if (mJavaEnv == NULL || result == NULL) return NS_ERROR_NULL_POINTER; -#if PROXY_JNI_CALLS - ExceptionOccurredMessage msg(result); +#if PROXY_JNI_CALLS + ExceptionOccurredMessage msg(this, result); sendMessageToJava(&msg); #else *result = mJavaEnv->ExceptionOccurred(); @@ -1497,14 +1500,20 @@ NS_IMETHODIMP CSecureEnv::ExceptionDescribe(void) return NS_OK; } +class ExceptionClearMessage : public JavaMessage { + CSecureEnv* secureEnv; +public: + ExceptionClearMessage(CSecureEnv* secureEnv) + { + this->secureEnv = secureEnv; + } + virtual void execute(JNIEnv* env) { secureEnv->clearPendingException(env); } +}; NS_IMETHODIMP CSecureEnv::ExceptionClear(void) { -#if PROXY_JNI_CALLS - class ExceptionClearMessage : public JavaMessage { - public: - virtual void execute(JNIEnv* env) { env->ExceptionClear(); } - } msg; +#if PROXY_JNI_CALLS + ExceptionClearMessage msg(this); sendMessageToJava(&msg); #else mJavaEnv->ExceptionClear(); @@ -2920,6 +2929,36 @@ void CSecureEnv::messageLoop(JNIEnv* env, JavaMessage* msg, JavaMessageQueue* se } } +void CSecureEnv::savePendingException(JNIEnv* env) +{ + // first off, always restore the env to a known state. + jthrowable pendingException = env->ExceptionOccurred(); + env->ExceptionClear(); + + if (mPendingException) + env->DeleteGlobalRef(mPendingException); + + if (pendingException) { + mPendingException = (jthrowable) env->NewGlobalRef(pendingException); + env->DeleteLocalRef(pendingException); + } +} + +jthrowable CSecureEnv::getPendingException(JNIEnv* env) +{ + if (mPendingException) + return (jthrowable) env->NewLocalRef(mPendingException); + return NULL; +} + +void CSecureEnv::clearPendingException(JNIEnv* env) +{ + if (mPendingException) { + env->DeleteGlobalRef(mPendingException); + mPendingException = NULL; + } +} + CSecureEnv* GetSecureJNI(JNIEnv* env, jobject thread) { CSecureEnv* secureJNI = NULL; diff --git a/plugin/oji/MRJCarbon/plugin/Source/CSecureEnv.h b/plugin/oji/MRJCarbon/plugin/Source/CSecureEnv.h index b6134aee974..19e6db086bf 100644 --- a/plugin/oji/MRJCarbon/plugin/Source/CSecureEnv.h +++ b/plugin/oji/MRJCarbon/plugin/Source/CSecureEnv.h @@ -35,9 +35,9 @@ * ----- END LICENSE BLOCK ----- */ /* - CSecureEnv.h - - Rewritten for use with MRJ plugin by Patrick C. Beard. + CSecureEnv.h + + Rewritten for use with MRJ plugin by Patrick C. Beard. */ #ifndef CSecureJNI2_h___ @@ -61,7 +61,7 @@ class CSecureEnv : public nsISecureEnv, public nsIRunnable, private SupportsMixi public: DECL_SUPPORTS_MIXIN - static NS_METHOD Create(MRJPlugin* plugin, JNIEnv* proxyEnv, const nsIID& aIID, void* *aInstancePtr); + static NS_METHOD Create(MRJPlugin* plugin, JNIEnv* proxyEnv, const nsIID& aIID, void* *aInstancePtr); //////////////////////////////////////////////////////////////////////////// // from nsISecureJNI2: @@ -302,7 +302,7 @@ public: /*[out]*/ jsize* result); NS_IMETHOD NewObjectArray(/*[in]*/ jsize len, - /*[in]*/ jclass clazz, + /*[in]*/ jclass clazz, /*[in]*/ jobject init, /*[out]*/ jobjectArray* result); @@ -365,49 +365,55 @@ public: CSecureEnv(MRJPlugin* plugin, JNIEnv* proxyEnv, JNIEnv* javaEnv = NULL); virtual ~CSecureEnv(void); - /** - * Called by the native run method, to connect the - * thread and the secure env. - */ - void initialize(JNIEnv* javaEnv, jboolean* isRunning, JavaMessageQueue* javaQueue, JavaMessageQueue* nativeQueue); - - jboolean isInitialized() { return mJavaQueue != NULL; } + /** + * Called by the native run method, to connect the + * thread and the secure env. + */ + void initialize(JNIEnv* javaEnv, jboolean* isRunning, JavaMessageQueue* javaQueue, JavaMessageQueue* nativeQueue); + + jboolean isInitialized() { return mJavaQueue != NULL; } - void setProxyEnv(JNIEnv* proxyEnv) { mProxyEnv = proxyEnv; } - JNIEnv* getProxyEnv() { return mProxyEnv; } - - void setJavaEnv(JNIEnv* javaEnv) { mJavaEnv = javaEnv; } - JNIEnv* getJavaEnv() { return mJavaEnv; } - - MRJSession* getSession() { return mSession; } - nsIThreadManager* getThreadManager() { return mThreadManager; } - - void getMessageQueues(JavaMessageQueue*& javaQueue, JavaMessageQueue*& nativeQueue) - { - javaQueue = mJavaQueue; - nativeQueue = mNativeQueue; - } - - void sendMessageToJava(JavaMessage* msg); - void sendMessageFromJava(JNIEnv* javaEnv, JavaMessage* msg, Boolean busyWaiting = false); - void messageLoop(JNIEnv* env, JavaMessage* msgToSend, JavaMessageQueue* sendQueue, JavaMessageQueue* receiveQueue, Boolean busyWaiting = false); - + void setProxyEnv(JNIEnv* proxyEnv) { mProxyEnv = proxyEnv; } + JNIEnv* getProxyEnv() { return mProxyEnv; } + + void setJavaEnv(JNIEnv* javaEnv) { mJavaEnv = javaEnv; } + JNIEnv* getJavaEnv() { return mJavaEnv; } + + MRJSession* getSession() { return mSession; } + nsIThreadManager* getThreadManager() { return mThreadManager; } + + void getMessageQueues(JavaMessageQueue*& javaQueue, JavaMessageQueue*& nativeQueue) + { + javaQueue = mJavaQueue; + nativeQueue = mNativeQueue; + } + + void sendMessageToJava(JavaMessage* msg); + void sendMessageFromJava(JNIEnv* javaEnv, JavaMessage* msg, Boolean busyWaiting = false); + void messageLoop(JNIEnv* env, JavaMessage* msgToSend, JavaMessageQueue* sendQueue, JavaMessageQueue* receiveQueue, Boolean busyWaiting = false); + + void savePendingException(JNIEnv* env); + jthrowable getPendingException(JNIEnv* env); + void clearPendingException(JNIEnv* env); + protected: - MRJPlugin* mPlugin; - JNIEnv* mProxyEnv; - MRJSession* mSession; - nsIThreadManager* mThreadManager; + MRJPlugin* mPlugin; + JNIEnv* mProxyEnv; + MRJSession* mSession; + nsIThreadManager* mThreadManager; - JNIEnv* mJavaEnv; - jboolean* mIsRunning; - JavaMessageQueue* mJavaQueue; - JavaMessageQueue* mNativeQueue; + JNIEnv* mJavaEnv; + jboolean* mIsRunning; + JavaMessageQueue* mJavaQueue; + JavaMessageQueue* mNativeQueue; + + jthrowable mPendingException; private: - // support for SupportsMixin. - static const InterfaceInfo sInterfaces[]; - static const UInt32 kInterfaceCount; + // support for SupportsMixin. + static const InterfaceInfo sInterfaces[]; + static const UInt32 kInterfaceCount; }; /**