Skip to content

Commit 887ef79

Browse files
committed
change MethodCallBaton to derive from NanAsyncWorker [see issue joeferner#135]
1 parent 81aede6 commit 887ef79

5 files changed

Lines changed: 76 additions & 93 deletions

File tree

src/javaObject.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
}
1313

1414
/*static*/ v8::Local<v8::Object> JavaObject::New(Java *java, jobject obj) {
15-
NanScope();
15+
NanEscapableScope();
1616

1717
JNIEnv *env = java->getJavaEnv();
1818
JavaScope javaScope(env);
@@ -81,7 +81,7 @@
8181
JavaObject *self = new JavaObject(java, obj);
8282
self->Wrap(javaObjectObj);
8383

84-
return javaObjectObj;
84+
return NanEscapeScope(javaObjectObj);
8585
}
8686

8787
JavaObject::JavaObject(Java *java, jobject obj) {

src/methodCallBaton.cpp

Lines changed: 64 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,18 @@
44
#include "javaObject.h"
55
#include "javaScope.h"
66

7-
MethodCallBaton::MethodCallBaton(Java* java, jobject method, jarray args, v8::Handle<v8::Value>& callback) {
7+
NanCallback* toNanCallback(v8::Handle<v8::Value>& callback) {
8+
if(callback->IsFunction()) {
9+
return new NanCallback(callback.As<v8::Function>());
10+
}
11+
return NULL;
12+
}
13+
14+
MethodCallBaton::MethodCallBaton(Java* java, jobject method, jarray args, v8::Handle<v8::Value>& callback) :
15+
NanAsyncWorker(toNanCallback(callback)) {
816
JNIEnv *env = java->getJavaEnv();
917
m_java = java;
1018
m_args = (jarray)env->NewGlobalRef(args);
11-
if(callback->IsFunction()) {
12-
m_callback = new NanCallback(v8::Handle<v8::Function>::Cast(callback));
13-
} else {
14-
m_callback = new NanCallback();
15-
}
1619
m_method = env->NewGlobalRef(method);
1720
m_error = NULL;
1821
m_result = NULL;
@@ -29,56 +32,41 @@ MethodCallBaton::~MethodCallBaton() {
2932
}
3033
env->DeleteGlobalRef(m_args);
3134
env->DeleteGlobalRef(m_method);
32-
delete m_callback;
3335
}
3436

3537
void MethodCallBaton::run() {
36-
uv_work_t* req = new uv_work_t();
37-
req->data = this;
38-
uv_queue_work(uv_default_loop(), req, MethodCallBaton::EIO_MethodCall, (uv_after_work_cb)MethodCallBaton::EIO_AfterMethodCall);
38+
NanAsyncQueueWorker(this);
3939
}
4040

4141
v8::Handle<v8::Value> MethodCallBaton::runSync() {
42-
JNIEnv *env = m_java->getJavaEnv();
43-
execute(env);
44-
return resultsToV8(env);
45-
}
46-
47-
/*static*/ void MethodCallBaton::EIO_MethodCall(uv_work_t* req) {
48-
MethodCallBaton* self = static_cast<MethodCallBaton*>(req->data);
49-
JNIEnv *env = javaGetEnv(self->m_java->getJvm(), self->m_java->getClassLoader());
50-
JavaScope javaScope(env);
51-
self->execute(env);
42+
m_env = m_java->getJavaEnv();
43+
ExecuteInternal();
44+
return resultsToV8(m_env);
5245
}
5346

54-
#if NODE_MINOR_VERSION >= 10
55-
/*static*/ void MethodCallBaton::EIO_AfterMethodCall(uv_work_t* req, int status) {
56-
#else
57-
/*static*/ void MethodCallBaton::EIO_AfterMethodCall(uv_work_t* req) {
58-
#endif
59-
MethodCallBaton* self = static_cast<MethodCallBaton*>(req->data);
60-
JNIEnv *env = self->m_java->getJavaEnv();
61-
JavaScope javaScope(env);
62-
self->after(env);
63-
delete req;
64-
delete self;
47+
void MethodCallBaton::Execute() {
48+
m_env = javaGetEnv(this->m_java->getJvm(), this->m_java->getClassLoader());
49+
ExecuteInternal();
6550
}
6651

67-
void MethodCallBaton::after(JNIEnv *env) {
52+
void MethodCallBaton::WorkComplete() {
6853
NanScope();
6954

70-
//on 0.11 we're getting segfault due to the scope closing.
71-
//v8 doesnt' let us create handles without having an open scope as of 0.11.
72-
v8::Handle<v8::Value> result = resultsToV8(env);
73-
v8::Handle<v8::Value> argv[2];
74-
if(result->IsNativeError()) {
75-
argv[0] = result;
76-
argv[1] = NanUndefined();
55+
v8::Handle<v8::Value> result = resultsToV8(m_env);
56+
if (result->IsNativeError()) {
57+
v8::Handle<v8::Value> argv[] = {
58+
result
59+
};
60+
callback->Call(1, argv);
7761
} else {
78-
argv[0] = NanUndefined();
79-
argv[1] = result;
62+
v8::Handle<v8::Value> argv[] = {
63+
NanUndefined(),
64+
result
65+
};
66+
callback->Call(2, argv);
8067
}
81-
m_callback->Call(2, argv);
68+
delete callback;
69+
callback = NULL;
8270
}
8371

8472
v8::Handle<v8::Value> MethodCallBaton::resultsToV8(JNIEnv *env) {
@@ -105,75 +93,75 @@ v8::Handle<v8::Value> MethodCallBaton::resultsToV8(JNIEnv *env) {
10593
return NanEscapeScope(javaToV8(m_java, env, m_result));
10694
}
10795

108-
void NewInstanceBaton::execute(JNIEnv *env) {
109-
jclass constructorClazz = env->FindClass("java/lang/reflect/Constructor");
110-
jmethodID constructor_newInstance = env->GetMethodID(constructorClazz, "newInstance", "([Ljava/lang/Object;)Ljava/lang/Object;");
96+
void NewInstanceBaton::ExecuteInternal() {
97+
jclass constructorClazz = m_env->FindClass("java/lang/reflect/Constructor");
98+
jmethodID constructor_newInstance = m_env->GetMethodID(constructorClazz, "newInstance", "([Ljava/lang/Object;)Ljava/lang/Object;");
11199

112-
//printf("invoke: %s\n", javaMethodCallToString(env, m_method, constructor_newInstance, m_args).c_str());
100+
//printf("invoke: %s\n", javaMethodCallToString(m_env, m_method, constructor_newInstance, m_args).c_str());
113101

114-
jobject result = env->CallObjectMethod(m_method, constructor_newInstance, m_args);
115-
if(env->ExceptionCheck()) {
116-
jthrowable ex = env->ExceptionOccurred();
117-
env->ExceptionClear();
118-
m_error = (jthrowable)env->NewGlobalRef(ex);
102+
jobject result = m_env->CallObjectMethod(m_method, constructor_newInstance, m_args);
103+
if(m_env->ExceptionCheck()) {
104+
jthrowable ex = m_env->ExceptionOccurred();
105+
m_env->ExceptionClear();
106+
m_error = (jthrowable)m_env->NewGlobalRef(ex);
119107
m_errorString = "Error creating class";
120108
return;
121109
}
122110

123-
m_result = env->NewGlobalRef(result);
111+
m_result = m_env->NewGlobalRef(result);
124112
}
125113

126-
void StaticMethodCallBaton::execute(JNIEnv *env) {
127-
jclass methodClazz = env->FindClass("java/lang/reflect/Method");
128-
jmethodID method_invoke = env->GetMethodID(methodClazz, "invoke", "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;");
114+
void StaticMethodCallBaton::ExecuteInternal() {
115+
jclass methodClazz = m_env->FindClass("java/lang/reflect/Method");
116+
jmethodID method_invoke = m_env->GetMethodID(methodClazz, "invoke", "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;");
129117

130118
/*
131-
printf("calling %s\n", javaObjectToString(env, m_method).c_str());
119+
printf("calling %s\n", javaObjectToString(m_env, m_method).c_str());
132120
printf("arguments\n");
133-
for(int i=0; i<env->GetArrayLength(m_args); i++) {
134-
printf(" %s\n", javaObjectToString(env, env->GetObjectArrayElement((jobjectArray)m_args, i)).c_str());
121+
for(int i=0; i<m_env->GetArrayLength(m_args); i++) {
122+
printf(" %s\n", javaObjectToString(m_env, m_env->GetObjectArrayElement((jobjectArray)m_args, i)).c_str());
135123
}
136124
*/
137125

138-
jobject result = env->CallObjectMethod(m_method, method_invoke, NULL, m_args);
126+
jobject result = m_env->CallObjectMethod(m_method, method_invoke, NULL, m_args);
139127

140-
if(env->ExceptionCheck()) {
141-
jthrowable ex = env->ExceptionOccurred();
142-
env->ExceptionClear();
143-
m_error = (jthrowable)env->NewGlobalRef(ex);
128+
if(m_env->ExceptionCheck()) {
129+
jthrowable ex = m_env->ExceptionOccurred();
130+
m_env->ExceptionClear();
131+
m_error = (jthrowable)m_env->NewGlobalRef(ex);
144132
m_errorString = "Error running static method";
145133
return;
146134
}
147135

148-
m_result = env->NewGlobalRef(result);
136+
m_result = m_env->NewGlobalRef(result);
149137
}
150138

151-
void InstanceMethodCallBaton::execute(JNIEnv *env) {
152-
jclass methodClazz = env->FindClass("java/lang/reflect/Method");
153-
jmethodID method_invoke = env->GetMethodID(methodClazz, "invoke", "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;");
139+
void InstanceMethodCallBaton::ExecuteInternal() {
140+
jclass methodClazz = m_env->FindClass("java/lang/reflect/Method");
141+
jmethodID method_invoke = m_env->GetMethodID(methodClazz, "invoke", "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;");
154142

155143
/*
156-
printf("calling %s\n", javaObjectToString(env, m_method).c_str());
144+
printf("calling %s\n", javaObjectToString(m_env, m_method).c_str());
157145
printf("arguments\n");
158-
for(int i=0; i<env->GetArrayLength(m_args); i++) {
159-
printf(" %s\n", javaObjectToString(env, env->GetObjectArrayElement((jobjectArray)m_args, i)).c_str());
146+
for(int i=0; i<m_env->GetArrayLength(m_args); i++) {
147+
printf(" %s\n", javaObjectToString(m_env, m_env->GetObjectArrayElement((jobjectArray)m_args, i)).c_str());
160148
}
161149
*/
162150

163-
jobject result = env->CallObjectMethod(m_method, method_invoke, m_javaObject->getObject(), m_args);
151+
jobject result = m_env->CallObjectMethod(m_method, method_invoke, m_javaObject->getObject(), m_args);
164152

165-
if(env->ExceptionCheck()) {
166-
jthrowable ex = env->ExceptionOccurred();
167-
env->ExceptionClear();
168-
m_error = (jthrowable)env->NewGlobalRef(ex);
153+
if(m_env->ExceptionCheck()) {
154+
jthrowable ex = m_env->ExceptionOccurred();
155+
m_env->ExceptionClear();
156+
m_error = (jthrowable)m_env->NewGlobalRef(ex);
169157
m_errorString = "Error running instance method";
170158
return;
171159
}
172160

173161
if(result == NULL) {
174162
m_result = NULL;
175163
} else {
176-
m_result = env->NewGlobalRef(result);
164+
m_result = m_env->NewGlobalRef(result);
177165
}
178166
}
179167

src/methodCallBaton.h

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,27 +12,22 @@
1212
class Java;
1313
class JavaObject;
1414

15-
class MethodCallBaton {
15+
class MethodCallBaton : public NanAsyncWorker {
1616
public:
1717
MethodCallBaton(Java* java, jobject method, jarray args, v8::Handle<v8::Value>& callback);
1818
virtual ~MethodCallBaton();
1919

20-
static void EIO_MethodCall(uv_work_t* req);
21-
#if NODE_MINOR_VERSION >= 10
22-
static void EIO_AfterMethodCall(uv_work_t* req, int status);
23-
#else
24-
static void EIO_AfterMethodCall(uv_work_t* req);
25-
#endif
2620
void run();
2721
v8::Handle<v8::Value> runSync();
2822

2923
protected:
30-
virtual void execute(JNIEnv *env) = 0;
31-
virtual void after(JNIEnv *env);
3224
v8::Handle<v8::Value> resultsToV8(JNIEnv *env);
25+
virtual void Execute();
26+
virtual void WorkComplete();
27+
virtual void ExecuteInternal() = 0;
3328

29+
JNIEnv *m_env;
3430
Java* m_java;
35-
NanCallback *m_callback;
3631
jthrowable m_error;
3732
std::string m_errorString;
3833
jarray m_args;
@@ -46,7 +41,7 @@ class InstanceMethodCallBaton : public MethodCallBaton {
4641
virtual ~InstanceMethodCallBaton();
4742

4843
protected:
49-
virtual void execute(JNIEnv *env);
44+
virtual void ExecuteInternal();
5045

5146
JavaObject* m_javaObject;
5247
};
@@ -57,7 +52,7 @@ class NewInstanceBaton : public MethodCallBaton {
5752
virtual ~NewInstanceBaton();
5853

5954
protected:
60-
virtual void execute(JNIEnv *env);
55+
virtual void ExecuteInternal();
6156

6257
jclass m_clazz;
6358
};
@@ -68,7 +63,7 @@ class StaticMethodCallBaton : public MethodCallBaton {
6863
virtual ~StaticMethodCallBaton();
6964

7065
protected:
71-
virtual void execute(JNIEnv *env);
66+
virtual void ExecuteInternal();
7267

7368
jclass m_clazz;
7469
};

src/utils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ std::string methodNotFoundToString(JNIEnv *env, jclass clazz, std::string method
111111
argsEnd--; \
112112
callbackProvided = true; \
113113
} else { \
114-
callback = NanNull(); \
114+
callback = NanNull(); \
115115
callbackProvided = false; \
116116
}
117117

test/java-callStaticMethod-test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ exports['Java - Call Static Method'] = nodeunit.testCase({
7979
"callStaticMethod bad number of args": function(test) {
8080
java.callStaticMethod("Test", "staticMethod", 42, "z", function(err, result) {
8181
test.ok(err);
82-
test.ok(!result);
82+
test.equals(undefined, result);
8383
test.done();
8484
});
8585
},

0 commit comments

Comments
 (0)