1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
14 * The Original Code is Java XPCOM Bindings.
16 * The Initial Developer of the Original Code is IBM Corporation.
17 * Portions created by the Initial Developer are Copyright (C) 2006
18 * IBM Corporation. All Rights Reserved.
21 * Javier Pedemonte (jhpedemonte@gmail.com)
23 * Alternatively, the contents of this file may be used under the terms of
24 * either the GNU General Public License Version 2 or later (the "GPL"), or
25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 * in which case the provisions of the GPL or the LGPL are applicable instead
27 * of those above. If you wish to allow use of your version of this file only
28 * under the terms of either the GPL or the LGPL, and not to allow others to
29 * use your version of this file under the terms of the MPL, indicate your
30 * decision by deleting the provisions above and replace them with the notice
31 * and other provisions required by the GPL or the LGPL. If you do not delete
32 * the provisions above, a recipient may use your version of this file under
33 * the terms of any one of the MPL, the GPL or the LGPL.
35 * ***** END LICENSE BLOCK ***** */
38 #include "nsXPCOMPrivate.h" // for XPCOM_DLL defines.
39 #include "nsXPCOMGlue.h"
43 #if defined(XP_WIN) || defined(XP_OS2)
44 #define JX_EXPORT JNIEXPORT
46 #define JX_EXPORT JNIEXPORT NS_EXPORT
50 /***********************
52 ***********************/
54 extern "C" JX_EXPORT jint JNICALL
55 JNI_OnLoad(JavaVM
* vm
, void* reserved
)
57 // Let the JVM know that we are using JDK 1.2 JNI features.
58 return JNI_VERSION_1_2
;
61 extern "C" JX_EXPORT
void JNICALL
62 JNI_OnUnload(JavaVM
* vm
, void* reserved
)
66 /********************************
67 * JavaXPCOM JNI interfaces
68 ********************************/
70 #define JXM_NATIVE(func) Java_org_mozilla_xpcom_internal_JavaXPCOMMethods_##func
76 kFunc_LockProfileDirectory
,
80 kFunc_GetComponentManager
,
81 kFunc_GetComponentRegistrar
,
82 kFunc_GetServiceManager
,
84 kFunc_CallXPCOMMethod
,
86 kFunc_IsSameXPCOMObject
,
87 kFunc_ReleaseProfileLock
,
88 kFunc_GetNativeHandleFromAWT
,
93 #define JX_NUM_FUNCS 18
96 // Get path string from java.io.File object.
98 GetJavaFilePath(JNIEnv
* env
, jobject aFile
)
100 jclass clazz
= env
->FindClass("java/io/File");
102 jmethodID pathMID
= env
->GetMethodID(clazz
, "getCanonicalPath",
103 "()Ljava/lang/String;");
105 return (jstring
) env
->CallObjectMethod(aFile
, pathMID
);
112 // Calls XPCOMGlueStartup using the given java.io.File object, and loads
113 // the JavaXPCOM methods from the XUL shared library.
115 LoadXULMethods(JNIEnv
* env
, jobject aXPCOMPath
, void** aFunctions
)
117 jstring pathString
= GetJavaFilePath(env
, aXPCOMPath
);
119 return NS_ERROR_FAILURE
;
120 const char* path
= env
->GetStringUTFChars(pathString
, nsnull
);
122 return NS_ERROR_OUT_OF_MEMORY
;
124 int len
= strlen(path
);
125 char* xpcomPath
= (char*) malloc(len
+ sizeof(XPCOM_DLL
) +
126 sizeof(XPCOM_FILE_PATH_SEPARATOR
) + 1);
128 return NS_ERROR_OUT_OF_MEMORY
;
129 sprintf(xpcomPath
, "%s" XPCOM_FILE_PATH_SEPARATOR XPCOM_DLL
, path
);
131 nsresult rv
= XPCOMGlueStartup(xpcomPath
);
137 // The JNICALL calling convention defines to "__stdcall" on Win32, which
139 nsDynamicFunctionLoad funcs
[] = {
140 { "_Java_org_mozilla_xpcom_internal_MozillaImpl_initialize@8",
141 (NSFuncPtr
*) &aFunctions
[kFunc_Initialize
] },
142 { "_Java_org_mozilla_xpcom_internal_GREImpl_initEmbedding@20",
143 (NSFuncPtr
*) &aFunctions
[kFunc_InitEmbedding
] },
144 { "_Java_org_mozilla_xpcom_internal_GREImpl_termEmbedding@8",
145 (NSFuncPtr
*) &aFunctions
[kFunc_TermEmbedding
] },
146 { "_Java_org_mozilla_xpcom_internal_GREImpl_lockProfileDirectory@12",
147 (NSFuncPtr
*) &aFunctions
[kFunc_LockProfileDirectory
] },
148 { "_Java_org_mozilla_xpcom_internal_GREImpl_notifyProfile@8",
149 (NSFuncPtr
*) &aFunctions
[kFunc_NotifyProfile
] },
150 { "_Java_org_mozilla_xpcom_internal_XPCOMImpl_initXPCOM@16",
151 (NSFuncPtr
*) &aFunctions
[kFunc_InitXPCOM
] },
152 { "_Java_org_mozilla_xpcom_internal_XPCOMImpl_shutdownXPCOM@12",
153 (NSFuncPtr
*) &aFunctions
[kFunc_ShutdownXPCOM
] },
154 { "_Java_org_mozilla_xpcom_internal_XPCOMImpl_getComponentManager@8",
155 (NSFuncPtr
*) &aFunctions
[kFunc_GetComponentManager
] },
156 { "_Java_org_mozilla_xpcom_internal_XPCOMImpl_getComponentRegistrar@8",
157 (NSFuncPtr
*) &aFunctions
[kFunc_GetComponentRegistrar
] },
158 { "_Java_org_mozilla_xpcom_internal_XPCOMImpl_getServiceManager@8",
159 (NSFuncPtr
*) &aFunctions
[kFunc_GetServiceManager
] },
160 { "_Java_org_mozilla_xpcom_internal_XPCOMImpl_newLocalFile@16",
161 (NSFuncPtr
*) &aFunctions
[kFunc_NewLocalFile
] },
162 { "_Java_org_mozilla_xpcom_internal_XPCOMJavaProxy_callXPCOMMethod@20",
163 (NSFuncPtr
*) &aFunctions
[kFunc_CallXPCOMMethod
] },
164 { "_Java_org_mozilla_xpcom_internal_XPCOMJavaProxy_finalizeProxy@12",
165 (NSFuncPtr
*) &aFunctions
[kFunc_FinalizeProxy
] },
166 { "_Java_org_mozilla_xpcom_internal_XPCOMJavaProxy_isSameXPCOMObject@16",
167 (NSFuncPtr
*) &aFunctions
[kFunc_IsSameXPCOMObject
] },
168 { "_Java_org_mozilla_xpcom_ProfileLock_release@16",
169 (NSFuncPtr
*) &aFunctions
[kFunc_ReleaseProfileLock
] },
170 { "_Java_org_mozilla_xpcom_internal_MozillaImpl_getNativeHandleFromAWT@12",
171 (NSFuncPtr
*) &aFunctions
[kFunc_GetNativeHandleFromAWT
] },
172 { "_Java_org_mozilla_xpcom_internal_JavaXPCOMMethods_wrapJavaObject@16",
173 (NSFuncPtr
*) &aFunctions
[kFunc_WrapJavaObject
] },
174 { "_Java_org_mozilla_xpcom_internal_JavaXPCOMMethods_wrapXPCOMObject@20",
175 (NSFuncPtr
*) &aFunctions
[kFunc_WrapXPCOMObject
] },
179 nsDynamicFunctionLoad funcs
[] = {
180 { "Java_org_mozilla_xpcom_internal_MozillaImpl_initialize",
181 (NSFuncPtr
*) &aFunctions
[kFunc_Initialize
] },
182 { "Java_org_mozilla_xpcom_internal_GREImpl_initEmbedding",
183 (NSFuncPtr
*) &aFunctions
[kFunc_InitEmbedding
] },
184 { "Java_org_mozilla_xpcom_internal_GREImpl_termEmbedding",
185 (NSFuncPtr
*) &aFunctions
[kFunc_TermEmbedding
] },
186 { "Java_org_mozilla_xpcom_internal_GREImpl_lockProfileDirectory",
187 (NSFuncPtr
*) &aFunctions
[kFunc_LockProfileDirectory
] },
188 { "Java_org_mozilla_xpcom_internal_GREImpl_notifyProfile",
189 (NSFuncPtr
*) &aFunctions
[kFunc_NotifyProfile
] },
190 { "Java_org_mozilla_xpcom_internal_XPCOMImpl_initXPCOM",
191 (NSFuncPtr
*) &aFunctions
[kFunc_InitXPCOM
] },
192 { "Java_org_mozilla_xpcom_internal_XPCOMImpl_shutdownXPCOM",
193 (NSFuncPtr
*) &aFunctions
[kFunc_ShutdownXPCOM
] },
194 { "Java_org_mozilla_xpcom_internal_XPCOMImpl_getComponentManager",
195 (NSFuncPtr
*) &aFunctions
[kFunc_GetComponentManager
] },
196 { "Java_org_mozilla_xpcom_internal_XPCOMImpl_getComponentRegistrar",
197 (NSFuncPtr
*) &aFunctions
[kFunc_GetComponentRegistrar
] },
198 { "Java_org_mozilla_xpcom_internal_XPCOMImpl_getServiceManager",
199 (NSFuncPtr
*) &aFunctions
[kFunc_GetServiceManager
] },
200 { "Java_org_mozilla_xpcom_internal_XPCOMImpl_newLocalFile",
201 (NSFuncPtr
*) &aFunctions
[kFunc_NewLocalFile
] },
202 { "Java_org_mozilla_xpcom_internal_XPCOMJavaProxy_callXPCOMMethod",
203 (NSFuncPtr
*) &aFunctions
[kFunc_CallXPCOMMethod
] },
204 { "Java_org_mozilla_xpcom_internal_XPCOMJavaProxy_finalizeProxy",
205 (NSFuncPtr
*) &aFunctions
[kFunc_FinalizeProxy
] },
206 { "Java_org_mozilla_xpcom_internal_XPCOMJavaProxy_isSameXPCOMObject",
207 (NSFuncPtr
*) &aFunctions
[kFunc_IsSameXPCOMObject
] },
208 { "Java_org_mozilla_xpcom_ProfileLock_release",
209 (NSFuncPtr
*) &aFunctions
[kFunc_ReleaseProfileLock
] },
210 { "Java_org_mozilla_xpcom_internal_MozillaImpl_getNativeHandleFromAWT",
211 (NSFuncPtr
*) &aFunctions
[kFunc_GetNativeHandleFromAWT
] },
212 { "Java_org_mozilla_xpcom_internal_JavaXPCOMMethods_wrapJavaObject",
213 (NSFuncPtr
*) &aFunctions
[kFunc_WrapJavaObject
] },
214 { "Java_org_mozilla_xpcom_internal_JavaXPCOMMethods_wrapXPCOMObject",
215 (NSFuncPtr
*) &aFunctions
[kFunc_WrapXPCOMObject
] },
220 rv
= XPCOMGlueLoadXULFunctions(funcs
);
228 ThrowException(JNIEnv
* env
, const nsresult aErrorCode
, const char* aMessage
)
230 // Only throw this exception if one hasn't already been thrown, so we don't
231 // mask a previous exception/error.
232 if (env
->ExceptionCheck())
235 // If the error code we get is for an Out Of Memory error, try to throw an
236 // OutOfMemoryError. The JVM may have enough memory to create this error.
237 if (aErrorCode
== NS_ERROR_OUT_OF_MEMORY
) {
238 jclass clazz
= env
->FindClass("java/lang/OutOfMemoryError");
240 env
->ThrowNew(clazz
, aMessage
);
242 env
->DeleteLocalRef(clazz
);
246 // If the error was not handled above, then create an XPCOMException with the
248 jthrowable throwObj
= nsnull
;
249 jclass exceptionClass
= env
->FindClass("org/mozilla/xpcom/XPCOMException");
250 if (exceptionClass
) {
251 jmethodID mid
= env
->GetMethodID(exceptionClass
, "<init>",
252 "(JLjava/lang/String;)V");
254 throwObj
= (jthrowable
) env
->NewObject(exceptionClass
, mid
,
255 (PRInt64
) aErrorCode
,
256 env
->NewStringUTF(aMessage
));
259 NS_ASSERTION(throwObj
, "Failed to create XPCOMException object");
263 env
->Throw(throwObj
);
267 // Register the JavaXPCOM native methods. This associates a native Java
268 // method with its C implementation.
270 RegisterNativeMethods(JNIEnv
* env
, void** aFunctions
)
272 JNINativeMethod mozilla_methods
[] = {
273 { "initializeNative", "()V",
274 (void*) aFunctions
[kFunc_Initialize
] },
275 { "getNativeHandleFromAWT", "(Ljava/lang/Object;)J",
276 (void*) aFunctions
[kFunc_GetNativeHandleFromAWT
] }
279 JNINativeMethod gre_methods
[] = {
280 { "initEmbeddingNative",
281 "(Ljava/io/File;Ljava/io/File;Lorg/mozilla/xpcom/IAppFileLocProvider;)V",
282 (void*) aFunctions
[kFunc_InitEmbedding
] },
283 { "termEmbedding", "()V",
284 (void*) aFunctions
[kFunc_TermEmbedding
] },
285 { "lockProfileDirectory", "(Ljava/io/File;)Lorg/mozilla/xpcom/ProfileLock;",
286 (void*) aFunctions
[kFunc_LockProfileDirectory
] },
287 { "notifyProfile", "()V",
288 (void*) aFunctions
[kFunc_NotifyProfile
] },
291 JNINativeMethod xpcom_methods
[] = {
293 "(Ljava/io/File;Lorg/mozilla/xpcom/IAppFileLocProvider;)Lorg/mozilla/interfaces/nsIServiceManager;",
294 (void*) aFunctions
[kFunc_InitXPCOM
] },
295 { "shutdownXPCOM", "(Lorg/mozilla/interfaces/nsIServiceManager;)V",
296 (void*) aFunctions
[kFunc_ShutdownXPCOM
] },
297 { "getComponentManager", "()Lorg/mozilla/interfaces/nsIComponentManager;",
298 (void*) aFunctions
[kFunc_GetComponentManager
] },
299 { "getComponentRegistrar", "()Lorg/mozilla/interfaces/nsIComponentRegistrar;",
300 (void*) aFunctions
[kFunc_GetComponentRegistrar
] },
301 { "getServiceManager", "()Lorg/mozilla/interfaces/nsIServiceManager;",
302 (void*) aFunctions
[kFunc_GetServiceManager
] },
303 { "newLocalFile", "(Ljava/lang/String;Z)Lorg/mozilla/interfaces/nsILocalFile;",
304 (void*) aFunctions
[kFunc_NewLocalFile
] }
307 JNINativeMethod proxy_methods
[] = {
309 "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;",
310 (void*) aFunctions
[kFunc_CallXPCOMMethod
] },
311 { "finalizeProxyNative", "(Ljava/lang/Object;)V",
312 (void*) aFunctions
[kFunc_FinalizeProxy
] },
313 { "isSameXPCOMObject", "(Ljava/lang/Object;Ljava/lang/Object;)Z",
314 (void*) aFunctions
[kFunc_IsSameXPCOMObject
] }
317 JNINativeMethod lockProxy_methods
[] = {
318 { "releaseNative", "(J)V",
319 (void*) aFunctions
[kFunc_ReleaseProfileLock
] }
322 JNINativeMethod util_methods
[] = {
323 { "wrapJavaObject", "(Ljava/lang/Object;Ljava/lang/String;)J",
324 (void*) aFunctions
[kFunc_WrapJavaObject
] },
325 { "wrapXPCOMObject", "(JLjava/lang/String;)Ljava/lang/Object;",
326 (void*) aFunctions
[kFunc_WrapXPCOMObject
] }
330 jclass clazz
= env
->FindClass("org/mozilla/xpcom/internal/MozillaImpl");
332 rc
= env
->RegisterNatives(clazz
, mozilla_methods
,
333 sizeof(mozilla_methods
) / sizeof(mozilla_methods
[0]));
335 NS_ENSURE_TRUE(rc
== 0, NS_ERROR_FAILURE
);
338 clazz
= env
->FindClass("org/mozilla/xpcom/internal/GREImpl");
340 rc
= env
->RegisterNatives(clazz
, gre_methods
,
341 sizeof(gre_methods
) / sizeof(gre_methods
[0]));
343 NS_ENSURE_TRUE(rc
== 0, NS_ERROR_FAILURE
);
346 clazz
= env
->FindClass("org/mozilla/xpcom/internal/XPCOMImpl");
348 rc
= env
->RegisterNatives(clazz
, xpcom_methods
,
349 sizeof(xpcom_methods
) / sizeof(xpcom_methods
[0]));
351 NS_ENSURE_TRUE(rc
== 0, NS_ERROR_FAILURE
);
354 clazz
= env
->FindClass("org/mozilla/xpcom/internal/XPCOMJavaProxy");
356 rc
= env
->RegisterNatives(clazz
, proxy_methods
,
357 sizeof(proxy_methods
) / sizeof(proxy_methods
[0]));
359 NS_ENSURE_TRUE(rc
== 0, NS_ERROR_FAILURE
);
362 clazz
= env
->FindClass("org/mozilla/xpcom/ProfileLock");
364 rc
= env
->RegisterNatives(clazz
, lockProxy_methods
,
365 sizeof(lockProxy_methods
) / sizeof(lockProxy_methods
[0]));
367 NS_ENSURE_TRUE(rc
== 0, NS_ERROR_FAILURE
);
370 clazz
= env
->FindClass("org/mozilla/xpcom/internal/JavaXPCOMMethods");
372 rc
= env
->RegisterNatives(clazz
, util_methods
,
373 sizeof(util_methods
) / sizeof(util_methods
[0]));
375 NS_ENSURE_TRUE(rc
== 0, NS_ERROR_FAILURE
);
380 // Load the JavaXPCOM methods from the XUL shared library, and registers them
381 // as Java native methods.
382 extern "C" JX_EXPORT
void JNICALL
383 JXM_NATIVE(registerJavaXPCOMMethodsNative
) (JNIEnv
*env
, jclass that
,
386 void* functions
[JX_NUM_FUNCS
];
387 memset(functions
, 0, JX_NUM_FUNCS
* sizeof(void*));
389 nsresult rv
= LoadXULMethods(env
, aXPCOMPath
, functions
);
390 if (NS_SUCCEEDED(rv
)) {
391 rv
= RegisterNativeMethods(env
, functions
);
395 ThrowException(env
, rv
, "Failed to register JavaXPCOM methods");