Skip to content

Commit 78f7de9

Browse files
committed
Use the provided custom class loader instead of the default system class loader (issue chromiumembedded#99)
1 parent 50705bc commit 78f7de9

10 files changed

Lines changed: 112 additions & 34 deletions

File tree

java/org/cef/CefApp.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,10 @@ private CefApp(String [] args, CefSettings settings)
158158
appHandler_ = this;
159159
}
160160

161+
// Perform native pre-initialization.
162+
if (!N_PreInitialize())
163+
throw new IllegalStateException("Failed to pre-initialize native code");
164+
161165
// On Mac we're registering a shutdown hook to shutdown the native CEF
162166
// part. This is useful if it is missed to call CefApp.disopse() before
163167
// System.exit(0). Unfortunately this approach works only for Mac because
@@ -607,6 +611,7 @@ public boolean accept(File dir, String name) {
607611
return library_path;
608612
}
609613

614+
private final native boolean N_PreInitialize();
610615
private final native boolean N_Initialize(String pathToJavaDLL,
611616
CefAppHandler appHandler, CefSettings settings);
612617
private final native void N_Shutdown();

native/CefApp.cpp

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,31 @@
3131
#include "signal_restore_posix.h"
3232
#endif
3333

34-
JNIEXPORT jboolean JNICALL Java_org_cef_CefApp_N_1Initialize
35-
(JNIEnv *env, jobject c, jstring argPathToJavaDLL, jobject appHandler,
36-
jobject jsettings) {
34+
JNIEXPORT jboolean JNICALL Java_org_cef_CefApp_N_1PreInitialize
35+
(JNIEnv *env, jobject c) {
3736
JavaVM* jvm;
3837
jint rs = env->GetJavaVM(&jvm);
39-
if (rs != JNI_OK) {
40-
ASSERT(false); // Not reached.
41-
return false;
42-
}
38+
ASSERT(rs == JNI_OK);
39+
if (rs != JNI_OK)
40+
return JNI_FALSE;
4341
SetJVM(jvm);
4442

43+
jobject javaClass = env->GetObjectClass(c);
44+
jobject javaClassLoader = NULL;
45+
JNI_CALL_METHOD(env, javaClass, "getClassLoader", "()Ljava/lang/ClassLoader;",
46+
Object, javaClassLoader);
47+
env->DeleteLocalRef(javaClass);
48+
ASSERT(javaClassLoader);
49+
if (!javaClassLoader)
50+
return JNI_FALSE;
51+
SetJavaClassLoader(env, javaClassLoader);
52+
53+
return JNI_TRUE;
54+
}
55+
56+
JNIEXPORT jboolean JNICALL Java_org_cef_CefApp_N_1Initialize
57+
(JNIEnv *env, jobject c, jstring argPathToJavaDLL, jobject appHandler,
58+
jobject jsettings) {
4559
#if defined(OS_WIN)
4660
CefMainArgs main_args(::GetModuleHandle(NULL));
4761
#else

native/CefApp.h

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

native/CefBrowser_N.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1546,7 +1546,7 @@ JNIEXPORT void JNICALL Java_org_cef_browser_CefBrowser_1N_N_1DragTargetDragEnter
15461546
GetCefFromJNIObject<CefDragData>(env, jdragData, "CefDragData");
15471547
if (!drag_data.get())
15481548
return;
1549-
jclass cls = env->FindClass("java/awt/event/MouseEvent");
1549+
jclass cls = FindClass(env, "java/awt/event/MouseEvent");
15501550
if (!cls)
15511551
return;
15521552

@@ -1561,7 +1561,7 @@ JNIEXPORT void JNICALL Java_org_cef_browser_CefBrowser_1N_N_1DragTargetDragEnter
15611561

15621562
JNIEXPORT void JNICALL Java_org_cef_browser_CefBrowser_1N_N_1DragTargetDragOver
15631563
(JNIEnv *env, jobject obj, jobject pos, jint jmodifiers, jint allowedOps) {
1564-
jclass cls = env->FindClass("java/awt/event/MouseEvent");
1564+
jclass cls = FindClass(env, "java/awt/event/MouseEvent");
15651565
if (!cls)
15661566
return;
15671567

@@ -1582,7 +1582,7 @@ JNIEXPORT void JNICALL Java_org_cef_browser_CefBrowser_1N_N_1DragTargetDragLeave
15821582

15831583
JNIEXPORT void JNICALL Java_org_cef_browser_CefBrowser_1N_N_1DragTargetDrop
15841584
(JNIEnv *env, jobject obj, jobject pos, jint jmodifiers) {
1585-
jclass cls = env->FindClass("java/awt/event/MouseEvent");
1585+
jclass cls = FindClass(env, "java/awt/event/MouseEvent");
15861586
if (!cls)
15871587
return;
15881588

native/client_app.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ void ClientApp::OnBeforeCommandLineProcessing(const CefString& process_type,
7373

7474
bool ClientApp::HandleTerminate() {
7575
BEGIN_ENV(env)
76-
jclass cls = env->FindClass("org/cef/CefApp");
76+
jclass cls = FindClass(env, "org/cef/CefApp");
7777
if (!cls) {
7878
return false;
7979
}

native/jni_util.cpp

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,19 @@
33
// can be found in the LICENSE file.
44

55
#include "jni_util.h"
6-
#include "client_handler.h"
6+
7+
#include <algorithm>
78
#include <jawt.h>
9+
10+
#include "client_handler.h"
811
#include "util.h"
912

1013
namespace {
1114

1215
JavaVM *g_jvm = NULL;
1316

17+
jobject g_javaClassLoader = NULL;
18+
1419
} // namespace
1520

1621
void SetJVM(JavaVM* jvm) {
@@ -57,6 +62,32 @@ void DetachFromThread(bool *mustDetach) {
5762
g_jvm->DetachCurrentThread();
5863
}
5964

65+
void SetJavaClassLoader(JNIEnv *env, jobject javaClassLoader) {
66+
ASSERT(!g_javaClassLoader);
67+
g_javaClassLoader = env->NewGlobalRef(javaClassLoader);
68+
}
69+
70+
jclass FindClass(JNIEnv* env, const char* class_name) {
71+
ASSERT(g_javaClassLoader);
72+
73+
std::string classNameSeparatedByDots(class_name);
74+
std::replace(classNameSeparatedByDots.begin(), classNameSeparatedByDots.end(), '/', '.');
75+
76+
jstring classNameJString = env->NewStringUTF(classNameSeparatedByDots.c_str());
77+
jobject result = NULL;
78+
79+
JNI_CALL_METHOD(env, g_javaClassLoader,
80+
"loadClass",
81+
"(Ljava/lang/String;)Ljava/lang/Class;",
82+
Object,
83+
result,
84+
classNameJString);
85+
86+
env->DeleteLocalRef(classNameJString);
87+
88+
return static_cast<jclass>(result);
89+
}
90+
6091
jobject NewJNIObject(JNIEnv* env, jclass cls) {
6192
jmethodID initID = env->GetMethodID(cls, "<init>", "()V");
6293
if(initID == 0) {
@@ -74,15 +105,15 @@ jobject NewJNIObject(JNIEnv* env, jclass cls) {
74105
}
75106

76107
jobject NewJNIObject(JNIEnv* env, const char* class_name) {
77-
jclass cls = env->FindClass(class_name);
108+
jclass cls = FindClass(env, class_name);
78109
if (!cls)
79110
return NULL;
80111

81112
return NewJNIObject(env, cls);
82113
}
83114

84115
jobject NewJNIObject(JNIEnv* env, const char* class_name, const char* sig, ...) {
85-
jclass cls = env->FindClass(class_name);
116+
jclass cls = FindClass(env, class_name);
86117
if (!cls)
87118
return NULL;
88119

@@ -213,7 +244,7 @@ jobject NewJNICookie(JNIEnv* env, const CefCookie& cookie) {
213244
CefCookie GetJNICookie(JNIEnv* env, jobject jcookie) {
214245
CefCookie cookie;
215246

216-
jclass cls = env->FindClass("org/cef/network/CefCookie");
247+
jclass cls = FindClass(env, "org/cef/network/CefCookie");
217248
if (!cls)
218249
return cookie;
219250

@@ -271,7 +302,7 @@ CefMessageRouterConfig GetJNIMessageRouterConfig(JNIEnv* env, jobject jConfig) {
271302
if (jConfig == NULL)
272303
return config;
273304
jclass cls =
274-
env->FindClass("org/cef/browser/CefMessageRouter$CefMessageRouterConfig");
305+
FindClass(env, "org/cef/browser/CefMessageRouter$CefMessageRouterConfig");
275306
if (cls == NULL)
276307
return config;
277308

@@ -362,7 +393,7 @@ jobjectArray NewJNIStringArray(JNIEnv* env,
362393
if(vals.empty())
363394
return NULL;
364395

365-
jclass cls = env->FindClass("java/lang/String");
396+
jclass cls = FindClass(env, "java/lang/String");
366397
if (!cls)
367398
return NULL;
368399

@@ -524,7 +555,7 @@ bool CallJNIMethodC_V(JNIEnv* env, jclass cls, jobject obj,
524555
CefPageRange GetJNIPageRange(JNIEnv* env, jobject obj) {
525556
CefPageRange range;
526557

527-
jclass cls = env->FindClass("org/cef/misc/CefPageRange");
558+
jclass cls = FindClass(env, "org/cef/misc/CefPageRange");
528559
if (!cls)
529560
return range;
530561

@@ -537,7 +568,7 @@ CefPageRange GetJNIPageRange(JNIEnv* env, jobject obj) {
537568
}
538569

539570
jobject NewJNIPageRange(JNIEnv* env, const CefPageRange& range) {
540-
jclass cls = env->FindClass("org/cef/misc/CefPageRange");
571+
jclass cls = FindClass(env, "org/cef/misc/CefPageRange");
541572
if (!cls)
542573
return NULL;
543574

@@ -557,7 +588,7 @@ jobject NewJNIPageRange(JNIEnv* env, const CefPageRange& range) {
557588
CefSize GetJNISize(JNIEnv* env, jobject obj) {
558589
CefSize size;
559590

560-
jclass cls = env->FindClass("java/awt/Dimension");
591+
jclass cls = FindClass(env, "java/awt/Dimension");
561592
if (!cls)
562593
return size;
563594

@@ -572,7 +603,7 @@ CefSize GetJNISize(JNIEnv* env, jobject obj) {
572603
CefRect GetJNIRect(JNIEnv* env, jobject obj) {
573604
CefRect rect;
574605

575-
jclass cls = env->FindClass("java/awt/Rectangle");
606+
jclass cls = FindClass(env, "java/awt/Rectangle");
576607
if (!cls)
577608
return rect;
578609

@@ -589,7 +620,7 @@ CefRect GetJNIRect(JNIEnv* env, jobject obj) {
589620
}
590621

591622
jobject NewJNIRect(JNIEnv* env, const CefRect& rect) {
592-
jclass cls = env->FindClass("java/awt/Rectangle");
623+
jclass cls = FindClass(env, "java/awt/Rectangle");
593624
if (!cls)
594625
return NULL;
595626

@@ -613,7 +644,7 @@ jobjectArray NewJNIRectArray(JNIEnv* env,
613644
if(vals.empty())
614645
return NULL;
615646

616-
jclass cls = env->FindClass("java/awt/Rectangle");
647+
jclass cls = FindClass(env, "java/awt/Rectangle");
617648
if (!cls)
618649
return NULL;
619650

@@ -629,7 +660,7 @@ jobjectArray NewJNIRectArray(JNIEnv* env,
629660
}
630661

631662
bool GetJNIPoint(JNIEnv* env, jobject obj, int* x, int* y) {
632-
jclass cls = env->FindClass("java/awt/Point");
663+
jclass cls = FindClass(env, "java/awt/Point");
633664
if (!cls)
634665
return false;
635666

@@ -643,7 +674,7 @@ bool GetJNIPoint(JNIEnv* env, jobject obj, int* x, int* y) {
643674

644675
// Create a new java.awt.Point.
645676
jobject NewJNIPoint(JNIEnv* env, int x, int y) {
646-
jclass cls = env->FindClass("java/awt/Point");
677+
jclass cls = FindClass(env, "java/awt/Point");
647678
if (!cls)
648679
return NULL;
649680

@@ -666,7 +697,7 @@ CefSettings GetJNISettings(JNIEnv* env, jobject obj) {
666697
if (!obj)
667698
return settings;
668699

669-
jclass cls = env->FindClass("org/cef/CefSettings");
700+
jclass cls = FindClass(env, "org/cef/CefSettings");
670701
if (!cls)
671702
return settings;
672703

@@ -782,7 +813,7 @@ jobjectArray GetAllJNIBrowser(JNIEnv* env, jobject jclientHandler) {
782813
}
783814

784815
jobject GetJNIEnumValue(JNIEnv* env, const char* class_name, const char* enum_valname) {
785-
jclass sourceCls = env->FindClass(class_name);
816+
jclass sourceCls = FindClass(env, class_name);
786817
if (!sourceCls)
787818
return NULL;
788819

native/jni_util.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,17 @@ jint GetJNIEnv(JNIEnv **env, bool *mustDetach);
3131
// END_ENV(e) INSTEAD.
3232
void DetachFromThread(bool *mustDetach);
3333

34+
// Sets the java class loader to use for creating java objects in native code.
35+
// We have to use a class loader instead of the JNIEnv::FindClass method
36+
// because JNIEnv::FindClass always uses the system class loader if called
37+
// from a non-Java thread, which will not work if the embedding Java code
38+
// uses a custom class loader for JCEF classes (e.g. in JavaWebStart).
39+
void SetJavaClassLoader(JNIEnv *env, jobject javaClassLoader);
40+
41+
// Returns a class with the given fully qualified |class_name| (with '/' as
42+
// separator).
43+
jclass FindClass(JNIEnv* env, const char* class_name);
44+
3445
// Helper macros to bind and release the JNI environment
3546
// to other threads than the JNI function was called on.
3647
#define BEGIN_ENV(e) \

native/render_handler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ int GetCursorId(cef_cursor_type_t type) {
1515
if(!env)
1616
return 0;
1717

18-
jclass cls = env->FindClass("java/awt/Cursor");
18+
jclass cls = FindClass(env, "java/awt/Cursor");
1919
if (!cls)
2020
return 0;
2121

native/util_win.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ std::string GetTempFileName(const std::string& identifer, bool useParentId) {
7878
static int getMouseEvent(const char* evtName) {
7979
int value = 0;
8080
BEGIN_ENV(env)
81-
jclass jcls = env->FindClass("java/awt/event/MouseEvent");
81+
jclass jcls = FindClass(env, "java/awt/event/MouseEvent");
8282
GetJNIFieldStaticInt(env, jcls, evtName, &value);
8383
END_ENV(env)
8484
return value;
@@ -92,7 +92,7 @@ static int getModifiers(BOOLEAN forceShift) {
9292
int button2 = 0;
9393
int button3 = 0;
9494
BEGIN_ENV(env)
95-
jclass jcls = env->FindClass("java/awt/event/InputEvent");
95+
jclass jcls = FindClass(env, "java/awt/event/InputEvent");
9696
if ((GetKeyState(VK_MENU) & 0x8000) != 0)
9797
GetJNIFieldStaticInt(env, jcls, "ALT_DOWN_MASK", &alt);
9898
if ((GetKeyState(VK_CONTROL) & 0x8000) != 0)
@@ -112,7 +112,7 @@ static int getModifiers(BOOLEAN forceShift) {
112112
static int getMouseButton(WPARAM wParam) {
113113
int mouseButton = 0;
114114
BEGIN_ENV(env)
115-
jclass jcls = env->FindClass("java/awt/event/MouseEvent");
115+
jclass jcls = FindClass(env, "java/awt/event/MouseEvent");
116116
switch (wParam) {
117117
case WM_LBUTTONDOWN:
118118
case WM_LBUTTONUP:

tools/make_jni_header.sh

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,20 @@ else
1111
if [ -z "$2" ]; then
1212
echo "ERROR: Please specify a class name"
1313
else
14-
export OUT_PATH="./native"
15-
export CLS_PATH="./third_party/jogamp/jar/*:./out/$1"
14+
if [ $1 == "macosx64" ]; then
15+
export CLS_OUT_PATH="./jcef_build/native/Release"
16+
if [ ! -d "$CLS_OUT_PATH" ]; then
17+
export CLS_OUT_PATH="./jcef_build/native/Debug"
18+
fi
19+
else
20+
export CLS_OUT_PATH="./out/$1"
21+
fi
22+
23+
export HEADER_PATH="./native"
24+
export CLS_PATH="./third_party/jogamp/jar/*:${CLS_OUT_PATH}"
1625
export CLS_NAME="${2##*.}"
1726

18-
javah -force -classpath $CLS_PATH -o $OUT_PATH/$CLS_NAME.h $2
27+
javah -force -classpath $CLS_PATH -o $HEADER_PATH/$CLS_NAME.h $2
1928
fi
2029
fi
2130

0 commit comments

Comments
 (0)