Skip to content

Commit 11eeaa1

Browse files
committed
Fix bug with extended asyncOptions when syncSuffix not 'Sync'.
1 parent 81872f3 commit 11eeaa1

File tree

8 files changed

+289
-18
lines changed

8 files changed

+289
-18
lines changed

lib/nodeJavaBridge.js

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,48 @@ 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+
var syncSuffix = undefined;
15+
var asyncSuffix = undefined;
16+
17+
var SyncCall = function(obj, method) {
18+
if (syncSuffix === undefined)
19+
throw new Error('Sync call made before jvm created');
20+
var syncMethodName = method + syncSuffix;
21+
if (syncMethodName in obj)
22+
return obj[syncMethodName].bind(obj);
23+
else
24+
throw new Error('Sync method not found:' + syncMethodName);
25+
}
26+
1427
java.onJvmCreated = function() {
1528
if (java.asyncOptions) {
16-
var suffix = java.asyncOptions.promiseSuffix;
29+
syncSuffix = java.asyncOptions.syncSuffix;
30+
asyncSuffix = java.asyncOptions.asyncSuffix;
31+
if (typeof syncSuffix !== 'string') {
32+
throw new Error('In asyncOptions, syncSuffix must be defined and must a string');
33+
}
34+
var promiseSuffix = java.asyncOptions.promiseSuffix;
1735
var promisify = java.asyncOptions.promisify;
18-
if (typeof suffix === 'string' && typeof promisify === 'function') {
36+
if (typeof promiseSuffix === 'string' && typeof promisify === 'function') {
1937
var methods = ['newInstance', 'callMethod', 'callStaticMethod'];
2038
methods.forEach(function (name) {
21-
java[name + suffix] = promisify(java[name]);
39+
java[name + promiseSuffix] = promisify(java[name]);
2240
});
41+
} else if (typeof promiseSuffix === 'undefined' && typeof promisify === 'undefined') {
42+
// no promises
43+
} else {
44+
throw new Error('In asyncOptions, if either promiseSuffix or promisify is defined, both most be.');
2345
}
46+
} else {
47+
syncSuffix = 'Sync';
48+
asyncSuffix = '';
2449
}
2550
}
2651

2752
var MODIFIER_PUBLIC = 1;
2853
var MODIFIER_STATIC = 8;
2954

55+
3056
java.import = function(name) {
3157
var clazz = java.findClassSync(name); // TODO: change to Class.forName when classloader issue is resolved.
3258
var result = function() {
@@ -41,11 +67,12 @@ java.import = function(name) {
4167
result.class = clazz;
4268

4369
// copy static fields
44-
var fields = clazz.getDeclaredFieldsSync();
70+
var fields = SyncCall(clazz, 'getDeclaredFields')();
4571
for (i = 0; i < fields.length; i++) {
46-
if (((fields[i].getModifiersSync() & MODIFIER_PUBLIC) === MODIFIER_PUBLIC)
47-
&& ((fields[i].getModifiersSync() & MODIFIER_STATIC) === MODIFIER_STATIC)) {
48-
var fieldName = fields[i].getNameSync();
72+
var modifiers = SyncCall(fields[i], 'getModifiers')();
73+
if (((modifiers & MODIFIER_PUBLIC) === MODIFIER_PUBLIC)
74+
&& ((modifiers & MODIFIER_STATIC) === MODIFIER_STATIC)) {
75+
var fieldName = SyncCall(fields[i], 'getName')();
4976
result.__defineGetter__(fieldName, function(name, fieldName) {
5077
return java.getStaticFieldValue(name, fieldName);
5178
}.bind(this, name, fieldName));
@@ -63,26 +90,30 @@ java.import = function(name) {
6390
}
6491

6592
// copy static methods
66-
var methods = clazz.getDeclaredMethodsSync();
93+
var methods = SyncCall(clazz, 'getDeclaredMethods')();
6794
for (i = 0; i < methods.length; i++) {
68-
if (((methods[i].getModifiersSync() & MODIFIER_PUBLIC) === MODIFIER_PUBLIC)
69-
&& ((methods[i].getModifiersSync() & MODIFIER_STATIC) === MODIFIER_STATIC)) {
70-
var methodName = methods[i].getNameSync();
71-
result[methodName + 'Sync'] = java.callStaticMethodSync.bind(java, name, methodName);
72-
result[methodName] = java.callStaticMethod.bind(java, name, methodName);
95+
var modifiers = SyncCall(methods[i], 'getModifiers')();
96+
if (((modifiers & MODIFIER_PUBLIC) === MODIFIER_PUBLIC)
97+
&& ((modifiers & MODIFIER_STATIC) === MODIFIER_STATIC)) {
98+
var methodName = SyncCall(methods[i], 'getName')();
99+
result[methodName + syncSuffix] = java.callStaticMethodSync.bind(java, name, methodName);
100+
if (typeof asyncSuffix === 'string') {
101+
result[methodName + asyncSuffix] = java.callStaticMethod.bind(java, name, methodName);
102+
}
73103
if (promisify) {
74104
result[methodName + promiseSuffix] = promisify(java.callStaticMethod.bind(java, name, methodName));
75105
}
76106
}
77107
}
78108

79109
// copy static classes/enums
80-
var classes = clazz.getDeclaredClassesSync();
110+
var classes = SyncCall(clazz, 'getDeclaredClasses')();
81111
for (i = 0; i < classes.length; i++) {
82-
if (((classes[i].getModifiersSync() & MODIFIER_PUBLIC) === MODIFIER_PUBLIC)
83-
&& ((classes[i].getModifiersSync() & MODIFIER_STATIC) === MODIFIER_STATIC)) {
84-
var className = classes[i].getNameSync();
85-
var simpleName = classes[i].getSimpleNameSync();
112+
var modifiers = SyncCall(classes[i], 'getModifiers')();
113+
if (((modifiers & MODIFIER_PUBLIC) === MODIFIER_PUBLIC)
114+
&& ((modifiers & MODIFIER_STATIC) === MODIFIER_STATIC)) {
115+
var className = SyncCall(classes[i], 'getName')();
116+
var simpleName = SyncCall(classes[i], 'getSimpleName')();
86117
Object.defineProperty(result, simpleName, {
87118
get: function(result, simpleName, className) {
88119
var c = java.import(className);

testAsyncOptions/testAllThreeSuffix.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,31 @@ module.exports = {
2828
test.done();
2929
},
3030

31+
testImportClass: function(test) {
32+
test.expect(3);
33+
// Note: java.import executes javascript code in lib/nodeJavaBridge that makes sync calls to java classes.
34+
var ArrayList = java.import("java.util.ArrayList");
35+
test.ok(ArrayList);
36+
var arrayList = new ArrayList();
37+
test.ok(arrayList);
38+
test.strictEqual(arrayList.sizeSync(), 0);
39+
test.done();
40+
},
41+
42+
testStaticAPI: function(test) {
43+
test.expect(6);
44+
var String = java.import("java.lang.String");
45+
test.ok(String);
46+
47+
var api = _.functions(String);
48+
test.ok(_.includes(api, 'formatSync'), 'Expected `formatSync` to be present, but it is NOT.');
49+
test.ok(_.includes(api, 'formatAsync'), 'Expected `formatAsync` to be present, but it is NOT.');
50+
test.ok(_.includes(api, 'formatPromise'), 'Expected `formatPromise` to be present, but it is NOT.');
51+
test.ok(!_.includes(api, 'format'), 'Expected `format` to NOT be present, but it is.');
52+
test.ok(!_.includes(api, 'formatundefined'), 'Expected `formatundefined` to NOT be present, but it is.');
53+
test.done();
54+
},
55+
3156
testSyncCalls: function(test) {
3257
test.expect(1);
3358
var arrayList = java.newInstanceSync("java.util.ArrayList");
@@ -37,6 +62,15 @@ module.exports = {
3762
test.done();
3863
},
3964

65+
testStaticSyncCalls: function(test) {
66+
test.expect(1);
67+
// Note: java.import executes javascript code in lib/nodeJavaBridge that makes sync calls to java classes.
68+
// Among other things, java.import creates Sync functions for static methods.
69+
var String = java.import("java.lang.String");
70+
test.strictEqual(String.formatSync('%s--%s', java.newArray("java.lang.String", ["hello", "world"])), "hello--world");
71+
test.done();
72+
},
73+
4074
testAsyncCalls: function(test) {
4175
test.expect(4);
4276
var arrayList = java.newInstanceSync("java.util.ArrayList");

testAsyncOptions/testAsyncSuffixSyncDefault.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,31 @@ module.exports = {
2525
test.done();
2626
},
2727

28+
testImportClass: function(test) {
29+
test.expect(3);
30+
// Note: java.import executes javascript code in lib/nodeJavaBridge that makes sync calls to java classes.
31+
var ArrayList = java.import("java.util.ArrayList");
32+
test.ok(ArrayList);
33+
var arrayList = new ArrayList();
34+
test.ok(arrayList);
35+
test.strictEqual(arrayList.size(), 0);
36+
test.done();
37+
},
38+
39+
testStaticAPI: function(test) {
40+
test.expect(6);
41+
var String = java.import("java.lang.String");
42+
test.ok(String);
43+
44+
var api = _.functions(String);
45+
test.ok(_.includes(api, 'format'), 'Expected `format` to be present, but it is NOT.');
46+
test.ok(_.includes(api, 'formatAsync'), 'Expected `formatAsync` to be present, but it is NOT.');
47+
test.ok(!_.includes(api, 'formatSync'), 'Expected `formatSync` to NOT be present, but it is.');
48+
test.ok(!_.includes(api, 'formatPromise'), 'Expected `formatPromise` to NOT be present, but it is.');
49+
test.ok(!_.includes(api, 'formatundefined'), 'Expected `formatundefined` to NOT be present, but it is.');
50+
test.done();
51+
},
52+
2853
testSyncCalls: function(test) {
2954
test.expect(1);
3055
var arrayList = java.newInstanceSync("java.util.ArrayList");
@@ -34,6 +59,15 @@ module.exports = {
3459
test.done();
3560
},
3661

62+
testStaticSyncCalls: function(test) {
63+
test.expect(1);
64+
// Note: java.import executes javascript code in lib/nodeJavaBridge that makes sync calls to java classes.
65+
// Among other things, java.import creates Sync functions for static methods.
66+
var String = java.import("java.lang.String");
67+
test.strictEqual(String.format('%s--%s', java.newArray("java.lang.String", ["hello", "world"])), "hello--world");
68+
test.done();
69+
},
70+
3771
testAsyncCalls: function(test) {
3872
test.expect(4);
3973
var arrayList = java.newInstanceSync("java.util.ArrayList");

testAsyncOptions/testDefacto.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,31 @@ module.exports = {
2525
test.done();
2626
},
2727

28+
testImportClass: function(test) {
29+
test.expect(3);
30+
// Note: java.import executes javascript code in lib/nodeJavaBridge that makes sync calls to java classes.
31+
var ArrayList = java.import("java.util.ArrayList");
32+
test.ok(ArrayList);
33+
var arrayList = new ArrayList();
34+
test.ok(arrayList);
35+
test.strictEqual(arrayList.sizeSync(), 0);
36+
test.done();
37+
},
38+
39+
testStaticAPI: function(test) {
40+
test.expect(6);
41+
var String = java.import("java.lang.String");
42+
test.ok(String);
43+
44+
var api = _.functions(String);
45+
test.ok(_.includes(api, 'format'), 'Expected `format` to be present, but it is NOT.');
46+
test.ok(_.includes(api, 'formatSync'), 'Expected `formatSync` to be present, but it is NOT.');
47+
test.ok(!_.includes(api, 'formatAsync'), 'Expected `formatAsync` to NOT be present, but it is.');
48+
test.ok(!_.includes(api, 'formatPromise'), 'Expected `formatPromise` to NOT be present, but it is.');
49+
test.ok(!_.includes(api, 'formatundefined'), 'Expected `formatundefined` to NOT be present, but it is.');
50+
test.done();
51+
},
52+
2853
testSyncCalls: function(test) {
2954
test.expect(1);
3055
var arrayList = java.newInstanceSync("java.util.ArrayList");
@@ -34,6 +59,15 @@ module.exports = {
3459
test.done();
3560
},
3661

62+
testStaticSyncCalls: function(test) {
63+
test.expect(1);
64+
// Note: java.import executes javascript code in lib/nodeJavaBridge that makes sync calls to java classes.
65+
// Among other things, java.import creates Sync functions for static methods.
66+
var String = java.import("java.lang.String");
67+
test.strictEqual(String.formatSync('%s--%s', java.newArray("java.lang.String", ["hello", "world"])), "hello--world");
68+
test.done();
69+
},
70+
3771
testAsyncCalls: function(test) {
3872
test.expect(4);
3973
var arrayList = java.newInstanceSync("java.util.ArrayList");

testAsyncOptions/testDefactoPlusPromise.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,31 @@ module.exports = {
2727
test.done();
2828
},
2929

30+
testImportClass: function(test) {
31+
test.expect(3);
32+
// Note: java.import executes javascript code in lib/nodeJavaBridge that makes sync calls to java classes.
33+
var ArrayList = java.import("java.util.ArrayList");
34+
test.ok(ArrayList);
35+
var arrayList = new ArrayList();
36+
test.ok(arrayList);
37+
test.strictEqual(arrayList.sizeSync(), 0);
38+
test.done();
39+
},
40+
41+
testStaticAPI: function(test) {
42+
test.expect(6);
43+
var String = java.import("java.lang.String");
44+
test.ok(String);
45+
46+
var api = _.functions(String);
47+
test.ok(_.includes(api, 'format'), 'Expected `format` to be present, but it is NOT.');
48+
test.ok(_.includes(api, 'formatSync'), 'Expected `formatSync` to be present, but it is NOT.');
49+
test.ok(_.includes(api, 'formatPromise'), 'Expected `formatPromise` to be present, but it is NOT.');
50+
test.ok(!_.includes(api, 'formatAsync'), 'Expected `formatAsync` to NOT be present, but it is.');
51+
test.ok(!_.includes(api, 'formatundefined'), 'Expected `formatundefined` to NOT be present, but it is.');
52+
test.done();
53+
},
54+
3055
testSyncCalls: function(test) {
3156
test.expect(1);
3257
var arrayList = java.newInstanceSync("java.util.ArrayList");
@@ -36,6 +61,15 @@ module.exports = {
3661
test.done();
3762
},
3863

64+
testStaticSyncCalls: function(test) {
65+
test.expect(1);
66+
// Note: java.import executes javascript code in lib/nodeJavaBridge that makes sync calls to java classes.
67+
// Among other things, java.import creates Sync functions for static methods.
68+
var String = java.import("java.lang.String");
69+
test.strictEqual(String.formatSync('%s--%s', java.newArray("java.lang.String", ["hello", "world"])), "hello--world");
70+
test.done();
71+
},
72+
3973
testAsyncCalls: function(test) {
4074
test.expect(4);
4175
var arrayList = java.newInstanceSync("java.util.ArrayList");

testAsyncOptions/testDefault.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,31 @@ module.exports = {
2323
test.done();
2424
},
2525

26+
testImportClass: function(test) {
27+
test.expect(3);
28+
// Note: java.import executes javascript code in lib/nodeJavaBridge that makes sync calls to java classes.
29+
var ArrayList = java.import("java.util.ArrayList");
30+
test.ok(ArrayList);
31+
var arrayList = new ArrayList();
32+
test.ok(arrayList);
33+
test.strictEqual(arrayList.sizeSync(), 0);
34+
test.done();
35+
},
36+
37+
testStaticAPI: function(test) {
38+
test.expect(6);
39+
var String = java.import("java.lang.String");
40+
test.ok(String);
41+
42+
var api = _.functions(String);
43+
test.ok(_.includes(api, 'format'), 'Expected `format` to be present, but it is NOT.');
44+
test.ok(_.includes(api, 'formatSync'), 'Expected `formatSync` to be present, but it is NOT.');
45+
test.ok(!_.includes(api, 'formatAsync'), 'Expected `formatAsync` to NOT be present, but it is.');
46+
test.ok(!_.includes(api, 'formatPromise'), 'Expected `formatPromise` to NOT be present, but it is.');
47+
test.ok(!_.includes(api, 'formatundefined'), 'Expected `formatundefined` to NOT be present, but it is.');
48+
test.done();
49+
},
50+
2651
testSyncCalls: function(test) {
2752
test.expect(1);
2853
var arrayList = java.newInstanceSync("java.util.ArrayList");
@@ -32,6 +57,15 @@ module.exports = {
3257
test.done();
3358
},
3459

60+
testStaticSyncCalls: function(test) {
61+
test.expect(1);
62+
// Note: java.import executes javascript code in lib/nodeJavaBridge that makes sync calls to java classes.
63+
// Among other things, java.import creates Sync functions for static methods.
64+
var String = java.import("java.lang.String");
65+
test.strictEqual(String.formatSync('%s--%s', java.newArray("java.lang.String", ["hello", "world"])), "hello--world");
66+
test.done();
67+
},
68+
3569
testAsyncCalls: function(test) {
3670
test.expect(4);
3771
var arrayList = java.newInstanceSync("java.util.ArrayList");

testAsyncOptions/testNoAsync.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,31 @@ module.exports = {
2727
test.done();
2828
},
2929

30+
testImportClass: function(test) {
31+
test.expect(3);
32+
// Note: java.import executes javascript code in lib/nodeJavaBridge that makes sync calls to java classes.
33+
var ArrayList = java.import("java.util.ArrayList");
34+
test.ok(ArrayList);
35+
var arrayList = new ArrayList();
36+
test.ok(arrayList);
37+
test.strictEqual(arrayList.sizeSync(), 0);
38+
test.done();
39+
},
40+
41+
testStaticAPI: function(test) {
42+
test.expect(6);
43+
var String = java.import("java.lang.String");
44+
test.ok(String);
45+
46+
var api = _.functions(String);
47+
test.ok(_.includes(api, 'formatSync'), 'Expected `formatSync` to be present, but it is NOT.');
48+
test.ok(_.includes(api, 'formatPromise'), 'Expected `formatPromise` to be present, but it is NOT.');
49+
test.ok(!_.includes(api, 'format'), 'Expected `format` to NOT be present, but it is.');
50+
test.ok(!_.includes(api, 'formatAsync'), 'Expected `formatAsync` to NOT be present, but it is.');
51+
test.ok(!_.includes(api, 'formatundefined'), 'Expected `formatundefined` to NOT be present, but it is.');
52+
test.done();
53+
},
54+
3055
testSyncCalls: function(test) {
3156
test.expect(1);
3257
var arrayList = java.newInstanceSync("java.util.ArrayList");
@@ -36,6 +61,15 @@ module.exports = {
3661
test.done();
3762
},
3863

64+
testStaticSyncCalls: function(test) {
65+
test.expect(1);
66+
// Note: java.import executes javascript code in lib/nodeJavaBridge that makes sync calls to java classes.
67+
// Among other things, java.import creates Sync functions for static methods.
68+
var String = java.import("java.lang.String");
69+
test.strictEqual(String.formatSync('%s--%s', java.newArray("java.lang.String", ["hello", "world"])), "hello--world");
70+
test.done();
71+
},
72+
3973
testPromiseCalls: function(test) {
4074
test.expect(1);
4175
var arrayList = java.newInstanceSync("java.util.ArrayList");

0 commit comments

Comments
 (0)