diff --git a/mozilla/extensions/java/xpcom/nsJavaInterfaces.cpp b/mozilla/extensions/java/xpcom/nsJavaInterfaces.cpp index bfbf6b34191..5b08dcce4e4 100644 --- a/mozilla/extensions/java/xpcom/nsJavaInterfaces.cpp +++ b/mozilla/extensions/java/xpcom/nsJavaInterfaces.cpp @@ -147,7 +147,7 @@ InitXPCOM_Impl(JNIEnv* env, jobject aMozBinDirectory, // create Java proxy for service manager returned by NS_InitXPCOM2 return GetNewOrUsedJavaObject(env, servMan, NS_GET_IID(nsIServiceManager), - aResult); + nsnull, aResult); } extern "C" NS_EXPORT jobject @@ -211,7 +211,7 @@ XPCOM_NATIVE(newLocalFile) (JNIEnv *env, jobject, jstring aPath, if (NS_SUCCEEDED(rv)) { jobject javaProxy; rv = GetNewOrUsedJavaObject(env, file, NS_GET_IID(nsILocalFile), - &javaProxy); + nsnull, &javaProxy); if (NS_SUCCEEDED(rv)) return javaProxy; } @@ -230,7 +230,7 @@ XPCOM_NATIVE(getComponentManager) (JNIEnv *env, jobject) if (NS_SUCCEEDED(rv)) { jobject javaProxy; rv = GetNewOrUsedJavaObject(env, cm, NS_GET_IID(nsIComponentManager), - &javaProxy); + nsnull, &javaProxy); if (NS_SUCCEEDED(rv)) return javaProxy; } @@ -249,7 +249,7 @@ XPCOM_NATIVE(getComponentRegistrar) (JNIEnv *env, jobject) if (NS_SUCCEEDED(rv)) { jobject javaProxy; rv = GetNewOrUsedJavaObject(env, cr, NS_GET_IID(nsIComponentRegistrar), - &javaProxy); + nsnull, &javaProxy); if (NS_SUCCEEDED(rv)) return javaProxy; } @@ -268,7 +268,7 @@ XPCOM_NATIVE(getServiceManager) (JNIEnv *env, jobject) if (NS_SUCCEEDED(rv)) { jobject javaProxy; rv = GetNewOrUsedJavaObject(env, sm, NS_GET_IID(nsIServiceManager), - &javaProxy); + nsnull, &javaProxy); if (NS_SUCCEEDED(rv)) return javaProxy; } diff --git a/mozilla/extensions/java/xpcom/nsJavaWrapper.cpp b/mozilla/extensions/java/xpcom/nsJavaWrapper.cpp index 19d726ddd47..0655541b7ff 100644 --- a/mozilla/extensions/java/xpcom/nsJavaWrapper.cpp +++ b/mozilla/extensions/java/xpcom/nsJavaWrapper.cpp @@ -1135,7 +1135,7 @@ FinalizeParams(JNIEnv *env, const nsXPTParamInfo &aParamInfo, PRUint8 aType, jobject java_obj = nsnull; if (xpcom_obj) { // Get matching Java object for given xpcom object - rv = GetNewOrUsedJavaObject(env, xpcom_obj, aIID, &java_obj); + rv = GetNewOrUsedJavaObject(env, xpcom_obj, aIID, nsnull, &java_obj); if (NS_FAILED(rv)) break; } @@ -1626,7 +1626,7 @@ JAVAPROXY_NATIVE(callXPCOMMethod) (JNIEnv *env, jclass that, jobject aJavaProxy, nsresult CreateJavaProxy(JNIEnv* env, nsISupports* aXPCOMObject, const nsIID& aIID, - jobject* aResult) + jobject aObjectLoader, jobject* aResult) { NS_PRECONDITION(aResult != nsnull, "null ptr"); if (!aResult) @@ -1656,9 +1656,9 @@ CreateJavaProxy(JNIEnv* env, nsISupports* aXPCOMObject, const nsIID& aIID, jobject java_obj = nsnull; // Create proper Java interface name - nsCAutoString class_name("org/mozilla/xpcom/"); + nsCAutoString class_name("org.mozilla.xpcom."); class_name.AppendASCII(iface_name); - jclass ifaceClass = env->FindClass(class_name.get()); + jclass ifaceClass = FindClassInLoader(env, aObjectLoader, class_name.get()); if (ifaceClass) { java_obj = env->CallStaticObjectMethod(xpcomJavaProxyClass, diff --git a/mozilla/extensions/java/xpcom/nsJavaWrapper.h b/mozilla/extensions/java/xpcom/nsJavaWrapper.h index 74dc63fc575..a468ead2e0d 100644 --- a/mozilla/extensions/java/xpcom/nsJavaWrapper.h +++ b/mozilla/extensions/java/xpcom/nsJavaWrapper.h @@ -48,13 +48,16 @@ * @param env pointer to Java context * @param aXPCOMObject XPCOM object to create proxy for * @param aIID IID for XPCOM object + * @param aObjectLoader Java object whose class loader we use for finding + * classes; can be null * @param aResult on exit, holds reference to Java proxy * * @return NS_OK if Java proxy was successfully created; * any other value denotes an error condition. */ nsresult CreateJavaProxy(JNIEnv* env, nsISupports* aXPCOMObject, - const nsIID& aIID, jobject* aResult); + const nsIID& aIID, jobject aObjectLoader, + jobject* aResult); /** * Returns the XPCOM object for which the given Java proxy was created. diff --git a/mozilla/extensions/java/xpcom/nsJavaXPCOMBindingUtils.cpp b/mozilla/extensions/java/xpcom/nsJavaXPCOMBindingUtils.cpp index af86093c679..34512157100 100644 --- a/mozilla/extensions/java/xpcom/nsJavaXPCOMBindingUtils.cpp +++ b/mozilla/extensions/java/xpcom/nsJavaXPCOMBindingUtils.cpp @@ -64,6 +64,7 @@ jclass nsISupportsClass = nsnull; jclass xpcomExceptionClass = nsnull; jclass xpcomJavaProxyClass = nsnull; jclass weakReferenceClass = nsnull; +jclass javaXPCOMUtilsClass = nsnull; jmethodID hashCodeMID = nsnull; jmethodID booleanValueMID = nsnull; @@ -88,6 +89,7 @@ jmethodID getNativeXPCOMInstMID = nsnull; jmethodID weakReferenceConstructorMID = nsnull; jmethodID getReferentMID = nsnull; jmethodID clearReferentMID = nsnull; +jmethodID findClassInLoaderMID = nsnull; #ifdef DEBUG_JAVAXPCOM jmethodID getNameMID = nsnull; @@ -275,6 +277,16 @@ InitializeJavaGlobals(JNIEnv *env) goto init_error; } + if (!(clazz = env->FindClass("org/mozilla/xpcom/internal/JavaXPCOMMethods")) || + !(javaXPCOMUtilsClass = (jclass) env->NewGlobalRef(clazz)) || + !(findClassInLoaderMID = env->GetStaticMethodID(clazz, + "findClassInLoader", + "(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Class;"))) + { + NS_WARNING("Problem creating org.mozilla.xpcom.internal.JavaXPCOMMethods globals"); + goto init_error; + } + #ifdef DEBUG_JAVAXPCOM if (!(clazz = env->FindClass("java/lang/Class")) || !(getNameMID = env->GetMethodID(clazz, "getName","()Ljava/lang/String;"))) @@ -795,7 +807,8 @@ JavaXPCOMInstance::~JavaXPCOMInstance() nsresult GetNewOrUsedJavaObject(JNIEnv* env, nsISupports* aXPCOMObject, - const nsIID& aIID, jobject* aResult) + const nsIID& aIID, jobject aObjectLoader, + jobject* aResult) { NS_PRECONDITION(aResult != nsnull, "null ptr"); if (!aResult) @@ -824,7 +837,7 @@ GetNewOrUsedJavaObject(JNIEnv* env, nsISupports* aXPCOMObject, // No Java object is associated with the given XPCOM object, so we // create a Java proxy. - return CreateJavaProxy(env, rootObject, aIID, aResult); + return CreateJavaProxy(env, rootObject, aIID, aObjectLoader, aResult); } nsresult diff --git a/mozilla/extensions/java/xpcom/nsJavaXPCOMBindingUtils.h b/mozilla/extensions/java/xpcom/nsJavaXPCOMBindingUtils.h index e5f3e699ecb..afcadc97e64 100644 --- a/mozilla/extensions/java/xpcom/nsJavaXPCOMBindingUtils.h +++ b/mozilla/extensions/java/xpcom/nsJavaXPCOMBindingUtils.h @@ -76,6 +76,7 @@ extern jclass nsISupportsClass; extern jclass xpcomExceptionClass; extern jclass xpcomJavaProxyClass; extern jclass weakReferenceClass; +extern jclass javaXPCOMUtilsClass; extern jmethodID hashCodeMID; extern jmethodID booleanValueMID; @@ -100,6 +101,7 @@ extern jmethodID getNativeXPCOMInstMID; extern jmethodID weakReferenceConstructorMID; extern jmethodID getReferentMID; extern jmethodID clearReferentMID; +extern jmethodID findClassInLoaderMID; #ifdef DEBUG_JAVAXPCOM extern jmethodID getNameMID; @@ -268,12 +270,15 @@ protected: * @param env Java environment pointer * @param aXPCOMObject XPCOM object for which to find/create Java object * @param aIID desired interface IID for Java object + * @param aObjectLoader Java object whose class loader we use for finding + * classes; can be null * @param aResult on success, holds reference to Java object * * @return NS_OK if succeeded; all other return values are error codes. */ nsresult GetNewOrUsedJavaObject(JNIEnv* env, nsISupports* aXPCOMObject, - const nsIID& aIID, jobject* aResult); + const nsIID& aIID, jobject aObjectLoader, + jobject* aResult); /** * Finds the associated XPCOM object for the given Java object and IID. If no @@ -297,6 +302,35 @@ nsresult GetIIDForMethodParam(nsIInterfaceInfo *iinfo, PRBool isFullVariantArray, nsID &result); +/** + * Returns the Class object associated with the class or interface with the + * given string name, using the class loader of the given object. + * + * @param env Java environment pointer + * @param aObjectLoader Java object whose class loader is used to load class + * @param aClassName fully qualified name of class to load + * + * @return java.lang.Class object of requested Class; NULL if the class + * wasn't found + * + * @see http://java.sun.com/j2se/1.3/docs/guide/jni/jni-12.html#classops + */ +inline jclass +FindClassInLoader(JNIEnv* env, jobject aObjectLoader, const char* aClassName) +{ + jclass clazz = nsnull; + jstring name = env->NewStringUTF(aClassName); + if (name) + clazz = (jclass) env->CallStaticObjectMethod(javaXPCOMUtilsClass, + findClassInLoaderMID, aObjectLoader, name); + +#ifdef DEBUG + if (!clazz) + fprintf(stderr, "WARNING: failed to find class [%s]\n", aClassName); +#endif + return clazz; +} + /******************************* * JNI helper functions diff --git a/mozilla/extensions/java/xpcom/nsJavaXPTCStub.cpp b/mozilla/extensions/java/xpcom/nsJavaXPTCStub.cpp index ad7a14483b5..ccd43edaec5 100644 --- a/mozilla/extensions/java/xpcom/nsJavaXPTCStub.cpp +++ b/mozilla/extensions/java/xpcom/nsJavaXPTCStub.cpp @@ -535,10 +535,6 @@ nsJavaXPTCStub::CallMethod(PRUint16 aMethodIndex, // Check for exception from called Java function jthrowable exp = env->ExceptionOccurred(); if (exp) { -#ifdef DEBUG - env->ExceptionDescribe(); -#endif - // If the exception is an instance of XPCOMException, then get the // nsresult from the exception instance. Else, default to // NS_ERROR_FAILURE. @@ -583,8 +579,13 @@ nsJavaXPTCStub::CallMethod(PRUint16 aMethodIndex, if (java_params) delete [] java_params; - LOG(("<--- (Java) %s::%s()\n", ifaceName, aMethodInfo->GetName())); +#ifdef DEBUG + if (env->ExceptionCheck()) + env->ExceptionDescribe(); +#endif env->ExceptionClear(); + + LOG(("<--- (Java) %s::%s()\n", ifaceName, aMethodInfo->GetName())); return rv; } @@ -918,7 +919,8 @@ nsJavaXPTCStub::SetupJavaParams(const nsXPTParamInfo &aParamInfo, jobject java_stub = nsnull; if (xpcom_obj) { // Get matching Java object for given xpcom object - rv = GetNewOrUsedJavaObject(env, xpcom_obj, iid, &java_stub); + jobject objLoader = env->CallObjectMethod(mJavaWeakRef, getReferentMID); + rv = GetNewOrUsedJavaObject(env, xpcom_obj, iid, objLoader, &java_stub); if (NS_FAILED(rv)) break; } diff --git a/mozilla/extensions/java/xpcom/src/JavaXPCOMMethods.java b/mozilla/extensions/java/xpcom/src/JavaXPCOMMethods.java index 5a6a5eed78a..098352aa5e5 100644 --- a/mozilla/extensions/java/xpcom/src/JavaXPCOMMethods.java +++ b/mozilla/extensions/java/xpcom/src/JavaXPCOMMethods.java @@ -60,5 +60,30 @@ public class JavaXPCOMMethods { public static native void registerJavaXPCOMMethodsNative(File aLibXULDirectory); + + /** + * Returns the Class object associated with the class or interface with the + * given string name, using the class loader of the given object. + * + * @param aObject the Java object whose class loader is used to load class + * @param aClassName the fully qualified name of desired class + * @return the Class object of requested Class; null if the + * class was not found + * + * @see http://java.sun.com/j2se/1.3/docs/guide/jni/jni-12.html#classops + */ + public static Class findClassInLoader(Object aObject, String aClassName) { + try { + if (aObject == null) { + return Class.forName(aClassName); + } else { + return Class.forName(aClassName, true, + aObject.getClass().getClassLoader()); + } + } catch (ClassNotFoundException e) { + return null; + } + } + }