Skip to content

Commit d6aef41

Browse files
committed
Promisify three async methods of Java module.
Joe, I implemented an onJvmCreated callback so I could do the promisification from javascript instead of C++. Let me know if you have reservations about this approach.
1 parent 80f543f commit d6aef41

File tree

4 files changed

+63
-21
lines changed

4 files changed

+63
-21
lines changed

lib/nodeJavaBridge.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,19 @@ java.classpath.push(path.resolve(__dirname, "../commons-lang3-node-java.jar"));
1111
java.classpath.push(path.resolve(__dirname, __dirname, "../src-java"));
1212
java.nativeBindingLocation = binaryPath;
1313

14+
java.onJvmCreated = function() {
15+
if (java.asyncOptions) {
16+
var suffix = java.asyncOptions.promiseSuffix;
17+
var promisify = java.asyncOptions.promisify;
18+
if (typeof suffix === 'string' && typeof promisify === 'function') {
19+
var methods = ['newInstance', 'callMethod', 'callStaticMethod'];
20+
methods.forEach(function (name) {
21+
java[name + suffix] = promisify(java[name]);
22+
});
23+
}
24+
}
25+
}
26+
1427
var MODIFIER_PUBLIC = 1;
1528
var MODIFIER_STATIC = 8;
1629

src/java.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,11 +185,20 @@ v8::Local<v8::Value> Java::createJVM(JavaVM** jvm, JNIEnv** env) {
185185

186186
m_classLoader = getSystemClassLoader(*env);
187187

188+
v8::Local<v8::Value> onJvmCreated = NanObjectWrapHandle(this)->Get(NanNew<v8::String>("onJvmCreated"));
189+
188190
// TODO: this handles sets put doesn't prevent modifing the underlying data. So java.classpath.push will still work which is invalid.
189191
NanObjectWrapHandle(this)->SetAccessor(NanNew<v8::String>("classpath"), AccessorProhibitsOverwritingGetter, AccessorProhibitsOverwritingSetter);
190192
NanObjectWrapHandle(this)->SetAccessor(NanNew<v8::String>("options"), AccessorProhibitsOverwritingGetter, AccessorProhibitsOverwritingSetter);
191193
NanObjectWrapHandle(this)->SetAccessor(NanNew<v8::String>("nativeBindingLocation"), AccessorProhibitsOverwritingGetter, AccessorProhibitsOverwritingSetter);
192194
NanObjectWrapHandle(this)->SetAccessor(NanNew<v8::String>("asyncOptions"), AccessorProhibitsOverwritingGetter, AccessorProhibitsOverwritingSetter);
195+
NanObjectWrapHandle(this)->SetAccessor(NanNew<v8::String>("onJvmCreated"), AccessorProhibitsOverwritingGetter, AccessorProhibitsOverwritingSetter);
196+
197+
if (onJvmCreated->IsFunction()) {
198+
v8::Local<v8::Function> onJvmCreatedFunc = onJvmCreated.As<v8::Function>();
199+
v8::Local<v8::Object> context = NanNew<v8::Object>();
200+
onJvmCreatedFunc->Call(context, 0, NULL);
201+
}
193202

194203
return NanNull();
195204
}
@@ -206,6 +215,8 @@ NAN_GETTER(Java::AccessorProhibitsOverwritingGetter) {
206215
NanReturnValue(NanNew<v8::String>(Java::s_nativeBindingLocation.c_str()));
207216
} else if(!strcmp("asyncOptions", *nameStr)) {
208217
NanReturnValue(self->m_asyncOptions);
218+
} else if(!strcmp("onJvmCreated", *nameStr)) {
219+
// There is no good reason to get onJvmCreated, so just fall through to error below.
209220
}
210221

211222
std::ostringstream errStr;

src/javaObject.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
funcTemplate->PrototypeTemplate()->Set(methodNameSync, methodCallSyncTemplate->GetFunction());
7070

7171
if (promisifying) {
72-
v8::Local<v8::Object> recv = asyncOptions; // just a dummy receiver
72+
v8::Local<v8::Object> recv = NanNew<v8::Object>();
7373
v8::Local<v8::Value> argv[] = { methodCallTemplate->GetFunction() };
7474
v8::Local<v8::Value> result = promisify->Call(recv, 1, argv);
7575
if (!result->IsFunction()) {

test/promises-test.js

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,27 @@ var java = require("../testHelpers").java;
33
var nodeunit = require("nodeunit");
44
var util = require("util");
55

6-
76
exports['Promises'] = nodeunit.testCase({
8-
97
"create an instance of a class and call methods (getClassPromise & getNamePromise)": function(test) {
108
// Adapted from a test in simple-test.js
119
java.newInstance("java.util.ArrayList", function(err, list) {
12-
if (err) {
13-
console.log(err);
14-
return;
15-
}
10+
test.ifError(err);
1611
test.ok(list);
17-
if (list) {
18-
list.getClassPromise()
19-
.then(function(clazz) { return clazz.getNamePromise(); })
20-
.then(function(name) {
21-
test.equal(name, "java.util.ArrayList");
22-
})
23-
.catch(function(err) {
24-
test.ifError(err);
25-
})
26-
.then(function() {
27-
test.expect(2);
28-
test.done();
29-
});
30-
}
12+
list.getClassPromise()
13+
.then(function(clazz) {
14+
test.ok(clazz);
15+
return clazz.getNamePromise();
16+
})
17+
.then(function(name) {
18+
test.equal(name, "java.util.ArrayList");
19+
})
20+
.catch(function(err) {
21+
test.ifError(err);
22+
})
23+
.then(function() {
24+
test.expect(4);
25+
test.done();
26+
});
3127
});
3228
},
3329

@@ -44,6 +40,28 @@ exports['Promises'] = nodeunit.testCase({
4440
test.expect(1);
4541
test.done();
4642
});
43+
},
44+
45+
"run promisified method of Java module (newInstancePromise)": function (test) {
46+
java.newInstancePromise("java.util.ArrayList")
47+
.then(function(list) {
48+
test.ok(list);
49+
return list.getClassPromise();
50+
})
51+
.then(function(clazz) {
52+
test.ok(clazz);
53+
return clazz.getNamePromise();
54+
})
55+
.then(function(name) {
56+
test.equal(name, "java.util.ArrayList");
57+
})
58+
.catch(function(err) {
59+
test.ifError(err);
60+
})
61+
.then(function() {
62+
test.expect(3);
63+
test.done();
64+
});
4765
}
4866
});
4967

0 commit comments

Comments
 (0)