Skip to content

Commit a1ee034

Browse files
committed
set classloader on new threads
1 parent b546809 commit a1ee034

5 files changed

Lines changed: 46 additions & 4 deletions

File tree

src/java.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ long my_getThreadId() {
3838
s_ct->InstanceTemplate()->SetInternalFieldCount(1);
3939
s_ct->SetClassName(v8::String::NewSymbol("Java"));
4040

41+
NODE_SET_PROTOTYPE_METHOD(s_ct, "getClassLoader", getClassLoader);
4142
NODE_SET_PROTOTYPE_METHOD(s_ct, "newInstance", newInstance);
4243
NODE_SET_PROTOTYPE_METHOD(s_ct, "newInstanceSync", newInstanceSync);
4344
NODE_SET_PROTOTYPE_METHOD(s_ct, "newProxy", newProxy);
@@ -146,9 +147,31 @@ v8::Handle<v8::Value> Java::createJVM(JavaVM** jvm, JNIEnv** env) {
146147
JNI_CreateJavaVM(&jvmTemp, (void **)env, &args);
147148
*jvm = jvmTemp;
148149

150+
m_classLoader = getSystemClassLoader(*env);
151+
149152
return v8::Undefined();
150153
}
151154

155+
/*static*/ v8::Handle<v8::Value> Java::getClassLoader(const v8::Arguments& args) {
156+
v8::HandleScope scope;
157+
Java* self = node::ObjectWrap::Unwrap<Java>(args.This());
158+
v8::Handle<v8::Value> ensureJvmResults = self->ensureJvm();
159+
if(!ensureJvmResults->IsUndefined()) {
160+
return ensureJvmResults;
161+
}
162+
JNIEnv* env = self->getJavaEnv();
163+
164+
jclass classClazz = env->FindClass("java/lang/ClassLoader");
165+
printf("%d\n", (int)classClazz);
166+
jmethodID class_getClassLoader = env->GetStaticMethodID(classClazz, "getSystemClassLoader", "()Ljava/lang/ClassLoader;");
167+
printf("%d\n", (int)class_getClassLoader);
168+
jobject classLoader = env->CallStaticObjectMethod(classClazz, class_getClassLoader);
169+
printf("%d\n", (int)classLoader);
170+
171+
jobject result = env->NewGlobalRef(classLoader);
172+
return scope.Close(javaToV8(self, env, result));
173+
}
174+
152175
/*static*/ v8::Handle<v8::Value> Java::newInstance(const v8::Arguments& args) {
153176
v8::HandleScope scope;
154177
Java* self = node::ObjectWrap::Unwrap<Java>(args.This());

src/java.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@ class Java : public node::ObjectWrap {
1212
static void Init(v8::Handle<v8::Object> target);
1313
JavaVM* getJvm() { return m_jvm; }
1414
JNIEnv* getJavaEnv() { return m_env; }
15+
jobject getClassLoader() { return m_classLoader; }
1516

1617
private:
1718
Java();
1819
~Java();
1920
v8::Handle<v8::Value> createJVM(JavaVM** jvm, JNIEnv** env);
2021

2122
static v8::Handle<v8::Value> New(const v8::Arguments& args);
23+
static v8::Handle<v8::Value> getClassLoader(const v8::Arguments& args);
2224
static v8::Handle<v8::Value> newInstance(const v8::Arguments& args);
2325
static v8::Handle<v8::Value> newInstanceSync(const v8::Arguments& args);
2426
static v8::Handle<v8::Value> newProxy(const v8::Arguments& args);
@@ -34,6 +36,7 @@ class Java : public node::ObjectWrap {
3436
static v8::Persistent<v8::FunctionTemplate> s_ct;
3537
JavaVM* m_jvm;
3638
JNIEnv* m_env;
39+
jobject m_classLoader;
3740
std::string m_classPath;
3841
};
3942

src/methodCallBaton.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ v8::Handle<v8::Value> MethodCallBaton::runSync() {
3535

3636
/*static*/ void MethodCallBaton::EIO_MethodCall(uv_work_t* req) {
3737
MethodCallBaton* self = static_cast<MethodCallBaton*>(req->data);
38-
JNIEnv *env = javaAttachCurrentThread(self->m_java->getJvm());
38+
JNIEnv *env = javaAttachCurrentThread(self->m_java->getJvm(), self->m_java->getClassLoader());
3939
self->execute(env);
4040
javaDetachCurrentThread(self->m_java->getJvm());
4141
}
@@ -148,7 +148,7 @@ void InstanceMethodCallBaton::execute(JNIEnv *env) {
148148
}
149149

150150
m_result = env->NewGlobalRef(result);
151-
POP_LOCAL_JAVA_FRAME();
151+
//todo: stack: POP_LOCAL_JAVA_FRAME();
152152
}
153153

154154
NewInstanceBaton::NewInstanceBaton(

src/utils.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,16 +86,31 @@ std::string javaMethodCallToString(JNIEnv *env, jobject obj, jmethodID methodId,
8686
return result.str();
8787
}
8888

89-
JNIEnv* javaAttachCurrentThread(JavaVM* jvm) {
89+
JNIEnv* javaAttachCurrentThread(JavaVM* jvm, jobject classLoader) {
9090
JNIEnv* env;
9191
JavaVMAttachArgs attachArgs;
9292
attachArgs.version = JNI_VERSION_1_4;
9393
attachArgs.name = NULL;
9494
attachArgs.group = NULL;
9595
jvm->AttachCurrentThread((void**)&env, &attachArgs);
96+
97+
jclass threadClazz = env->FindClass("java/lang/Thread");
98+
jmethodID thread_currentThread = env->GetStaticMethodID(threadClazz, "currentThread", "()Ljava/lang/Thread;");
99+
jmethodID thread_setContextClassLoader = env->GetMethodID(threadClazz, "setContextClassLoader", "(Ljava/lang/ClassLoader;)V");
100+
jobject currentThread = env->CallStaticObjectMethod(threadClazz, thread_currentThread);
101+
env->CallObjectMethod(currentThread, thread_setContextClassLoader, classLoader);
102+
96103
return env;
97104
}
98105

106+
jobject getSystemClassLoader(JNIEnv *env) {
107+
jclass threadClazz = env->FindClass("java/lang/Thread");
108+
jmethodID thread_currentThread = env->GetStaticMethodID(threadClazz, "currentThread", "()Ljava/lang/Thread;");
109+
jmethodID thread_getContextClassLoader = env->GetMethodID(threadClazz, "getContextClassLoader", "()Ljava/lang/ClassLoader;");
110+
jobject currentThread = env->CallStaticObjectMethod(threadClazz, thread_currentThread);
111+
return env->CallObjectMethod(currentThread, thread_getContextClassLoader);
112+
}
113+
99114
void javaDetachCurrentThread(JavaVM* jvm) {
100115
jvm->DetachCurrentThread();
101116
}

src/utils.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,9 @@ void javaReflectionGetFields(JNIEnv *env, jclass clazz, std::list<jobject>* fiel
5050
std::string javaToString(JNIEnv *env, jstring str);
5151
std::string javaObjectToString(JNIEnv *env, jobject obj);
5252
std::string javaMethodCallToString(JNIEnv *env, jobject obj, jmethodID methodId, jarray args);
53-
JNIEnv* javaAttachCurrentThread(JavaVM* jvm);
53+
JNIEnv* javaAttachCurrentThread(JavaVM* jvm, jobject classLoader);
5454
void javaDetachCurrentThread(JavaVM* jvm);
55+
jobject getSystemClassLoader(JNIEnv *env);
5556
jvalueType javaGetType(JNIEnv *env, jclass type);
5657
jobjectArray v8ToJava(JNIEnv* env, const v8::Arguments& args, int start, int end);
5758
jobject v8ToJava(JNIEnv* env, v8::Local<v8::Value> arg);

0 commit comments

Comments
 (0)