Skip to content

Commit d4b66aa

Browse files
committed
remove asyncOptions.promisify and always use utils.promisify
1 parent 478a9d1 commit d4b66aa

16 files changed

+41
-111
lines changed

README.md

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,6 @@ java.asyncOptions = {
242242
asyncSuffix: undefined, // Don't generate node-style methods taking callbacks
243243
syncSuffix: "", // Sync methods use the base name(!!)
244244
promiseSuffix: "Promise", // Generate methods returning promises, using the suffix Promise.
245-
promisify: require('util').promisify // Needs Node.js version 8 or greater, see comment below
246245
};
247246
java.classpath.push("commons-lang3-3.1.jar");
248247
java.classpath.push("commons-io.jar");
@@ -259,15 +258,12 @@ java.newInstancePromise("java.util.ArrayList")
259258

260259
* If you want the defacto standard behavior, simply don't set java.asyncOptions.
261260
* If you do provide asyncOptions, be aware that this module will not generate method variants of a given flavor if you don't provide a string value for the corresponding suffix (`asyncSuffix`, `syncSuffix`, `promiseSuffix`). In the example above, the application is configured to omit the method variants using node-style async callback functions.
262-
* If you provide `asyncOptions.promiseSuffix` then you must also set `asyncOptions.promisify` to a function that *promisifies* a node-style async function. I.e. the provided function must take as input a function whose last argument is a node callback function, and it must return an equivalent promise-returning function. Several Promises/A+ libraries provide such functions, but it may be necessary to provide a wrapper function. See `testHelpers.js` for an example.
263-
* For `promisify` implementation, if you are using Node.js version 8.0.0 or newer then `promisify: require('util').promisify` will work out of the box. If you need to support and older Node.js version then an implementation needs to be provided, for example, `promisify: require("when/node").lift`
264-
* If you provide `asyncOptions.promisify` then you must provide a *non-empty* string for `asyncOptions.promiseSuffix`.
265261
* Either (but not both) `asyncSuffix` or `syncSuffix` can be the empty string. If you want the defacto standard behavior for no suffix on async methods, you must provide an empty string for `asyncSuffix`.
266262
* We've tested promises with five Promises/A+ implementations. See `testHelpers.js` for more information.
267263
* NOTE: Due to specifics of initialization order, the methods `java.newInstancePromise`, `java.callMethodPromise`, and `java.callStaticMethodPromise` are not available until the JVM has been created. You may need to call some other java method such as `java.import()` to finalize java initialization, or even better, the function `java.ensureJvm()`.
268264

269265
##### Special note about the exported module functions `newInstance`, `callMethod`, and `callStaticMethod`.
270-
These methods come in both async and sync variants. If you provide the `promisify` and `promiseSuffix` attributes in asyncOptions then you'll also get the Promises/A+ variant for these three functions. However, if you change the defacto conventions for the `syncSuffix` (i.e. 'Sync') and/or `asyncSuffix` (i.e. '') it will not affect the naming for these three functions. I.e. no matter what you specify in asyncOptions, the async variants are named `newInstance`, `callMethod`, and `callStaticMethod`, and the sync variants are named `newInstanceSync`, `callMethodSync`, and `callStaticMethodSync`.
266+
These methods come in both async and sync variants. If you provide the `promiseSuffix` attributes in asyncOptions then you'll also get the Promises/A+ variant for these three functions. However, if you change the defacto conventions for the `syncSuffix` (i.e. 'Sync') and/or `asyncSuffix` (i.e. '') it will not affect the naming for these three functions. I.e. no matter what you specify in asyncOptions, the async variants are named `newInstance`, `callMethod`, and `callStaticMethod`, and the sync variants are named `newInstanceSync`, `callMethodSync`, and `callStaticMethodSync`.
271267

272268
## Varargs support
273269

@@ -375,15 +371,13 @@ java.asyncOptions = {
375371
asyncSuffix: undefined, // Don't generate node-style methods taking callbacks
376372
syncSuffix: "", // Sync methods use the base name(!!)
377373
promiseSuffix: "Promise", // Generate methods returning promises, using the suffix Promise.
378-
promisify: require('util').promisify // Needs Node.js version 8 or greater, see comment below
379374
ifReadOnlySuffix: "_alt"
380375
};
381376
```
382377

383378
* `asyncSuffix` Suffix for callback-based async method call signatures.
384379
* `syncSuffix` Suffix for synchronous method call signatures.
385380
* `promiseSuffix` Suffix for promise-based async method call signatures
386-
* `promisify` Callback-to-promise transform implementation. From Node.js version 8 one can just use Node.js implementation: `promisify: require('util').promisify`.
387381
* `ifReadOnlySuffix` See [Static Member Name Conflicts](#staticMemberNameConflicts).
388382

389383
See [Async Options](#asyncOptionsDetails) for details.

java.d.ts

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,12 @@ declare namespace NodeJavaCore {
1616
(err?: JavaError, result?: T): void;
1717
}
1818

19-
interface Promisify {
20-
(fn: Function, receiver?: any): Function;
21-
}
22-
2319
interface AsyncOptions {
2420
/**
2521
* Suffix for synchronous method call signatures.
2622
*/
2723
syncSuffix: string;
28-
24+
2925
/**
3026
* Suffix for callback-based async method call signatures.
3127
*/
@@ -36,12 +32,6 @@ declare namespace NodeJavaCore {
3632
*/
3733
promiseSuffix?: string | undefined;
3834

39-
/**
40-
* Callback-to-promise transform implementation. From Node.js version 8 one can
41-
* just use Node.js implementation: `promisify: require('util').promisify`.
42-
*/
43-
promisify?: Promisify | undefined;
44-
4535
/**
4636
* The JavaScript object returned by `java.import(classname)` is a JavaScript constructor
4737
* Function, implemented such that you can create instances of the Java class. For example:
@@ -56,9 +46,9 @@ declare namespace NodeJavaCore {
5646
interface Java {
5747
/**
5848
* Array of paths or jars to pass to the creation of the JVM.
59-
*
49+
*
6050
* All items must be added to the classpath before calling any other node-java methods.
61-
*
51+
*
6252
* @example
6353
* java.classpath.push('commons.io.jar');
6454
* java.classpath.push('src');
@@ -67,9 +57,9 @@ declare namespace NodeJavaCore {
6757

6858
/**
6959
* Array of options to pass to the creation of the JVM.
70-
*
60+
*
7161
* All items must be added to the options before calling any other node-java methods.
72-
*
62+
*
7363
* @example
7464
* java.options.push('-Djava.awt.headless=true');
7565
* java.options.push('-Xmx1024m');

package-lock.json

Lines changed: 1 addition & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,14 @@
3535
"@eslint/js": "^9.27.0",
3636
"@types/find-root": "^1.1.4",
3737
"@types/node": "^22.15.21",
38-
"@types/when": "^2.4.41",
3938
"chalk": "2.4.2",
4039
"eslint": "^9.27.0",
4140
"find-root": "^1.1.0",
4241
"globals": "^16.1.0",
4342
"prettier": "^3.5.3",
4443
"typescript": "^5.8.3",
4544
"typescript-eslint": "^8.32.1",
46-
"vitest": "^3.1.3",
47-
"when": "3.7.8"
45+
"vitest": "^3.1.3"
4846
},
4947
"scripts": {
5048
"install": "node-gyp rebuild",

src-cpp/java.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -190,13 +190,6 @@ void Java::configureAsync(v8::Local<v8::Value> &asyncOptions) {
190190
v8::Local<v8::String> suffix = suffixValue->ToString(Nan::GetCurrentContext()).ToLocalChecked();
191191
Nan::Utf8String utf8(suffix);
192192
m_PromiseSuffix.assign(*utf8);
193-
v8::MaybeLocal<v8::Value> maybePromisify =
194-
Nan::Get(asyncOptionsObj, Nan::New<v8::String>("promisify").ToLocalChecked());
195-
v8::Local<v8::Value> promisify;
196-
if (maybePromisify.ToLocal(&promisify) && !promisify->IsFunction()) {
197-
fprintf(stderr, "asyncOptions.promisify must be a function");
198-
assert(promisify->IsFunction());
199-
}
200193
doPromise = true;
201194
}
202195

src-cpp/javaObject.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,9 @@
2828

2929
v8::Local<v8::Function> promisify;
3030
if (java->DoPromise()) {
31-
v8::Local<v8::Object> asyncOptions =
32-
java->handle()
33-
->Get(Nan::GetCurrentContext(), Nan::New<v8::String>("asyncOptions").ToLocalChecked())
34-
.ToLocalChecked()
35-
.As<v8::Object>();
3631
v8::Local<v8::Value> promisifyValue =
37-
asyncOptions->Get(Nan::GetCurrentContext(), Nan::New<v8::String>("promisify").ToLocalChecked())
32+
java->handle()
33+
->Get(Nan::GetCurrentContext(), Nan::New<v8::String>("promisify").ToLocalChecked())
3834
.ToLocalChecked();
3935
promisify = promisifyValue.As<v8::Function>();
4036
}
@@ -78,7 +74,7 @@
7874
v8::Local<v8::Value> argv[] = {methodCallTemplate->GetFunction(Nan::GetCurrentContext()).ToLocalChecked()};
7975
v8::Local<v8::Value> result = Nan::Call(promisify, recv, 1, argv).FromMaybe(v8::Local<v8::Value>());
8076
if (!result->IsFunction()) {
81-
fprintf(stderr, "Promisified result is not a function -- asyncOptions.promisify must return a function.\n");
77+
fprintf(stderr, "Promisified result is not a function.\n");
8278
assert(result->IsFunction());
8379
}
8480
v8::Local<v8::Function> promFunction = result.As<v8::Function>();

src-node/nodeJavaBridge.js

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ process.env.PATH += require("../build/jvm_dll_path.json");
44

55
const path = require("path");
66
const fs = require("fs");
7+
const util = require("util");
8+
79
let binaryPath = null;
810
try {
911
if (fs.statSync && fs.statSync(path.join(__dirname, "../build/Debug/nodejavabridge_bindings.node")).isFile()) {
@@ -19,6 +21,7 @@ if (!binaryPath) {
1921
const bindings = require(binaryPath);
2022

2123
const java = (module.exports = new bindings.Java());
24+
java.promisify = util.promisify;
2225
java.classpath.push(path.resolve(__dirname, "../src-java/commons-lang3-node-java.jar"));
2326
java.classpath.push(path.resolve(__dirname, __dirname, "../src-java"));
2427
java.classpath.pushDir = function (dir) {
@@ -146,18 +149,15 @@ async function initializeAll() {
146149
// This function ensures that the JVM has been launched, asynchronously. The application can be notified
147150
// when the JVM is fully created via either a node callback function, or via a promise.
148151
// If the parameter `callback` is provided, it is assume be a node callback function.
149-
// If the parameter is not provided, and java.asyncOptions.promisify has been specified,
150-
// then this function will return a promise, by promisifying itself and then calling that
151-
// promisified function.
152152
// This function may be called multiple times -- the 2nd and subsequent calls are no-ops.
153153
// However, once this method has been called (or the JVM is launched as a side effect of calling other java
154154
// methods), then clients can no longer use the registerClient API.
155155
java.ensureJvm = function (callback) {
156156
// First see if the promise-style API should be used.
157157
// This must be done first in order to ensure the proper API is used.
158-
if (typeof callback === "undefined" && java.asyncOptions && typeof java.asyncOptions.promisify === "function") {
158+
if (typeof callback === "undefined") {
159159
// Create a promisified version of this function.
160-
const launchJvmPromise = java.asyncOptions.promisify(java.ensureJvm.bind(java));
160+
const launchJvmPromise = util.promisify(java.ensureJvm.bind(java));
161161
// Call the promisified function, returning its result, which should be a promise.
162162
return launchJvmPromise();
163163
}
@@ -194,16 +194,11 @@ java.onJvmCreated = function () {
194194
throw new Error("In asyncOptions, syncSuffix must be defined and must a string");
195195
}
196196
const promiseSuffix = java.asyncOptions.promiseSuffix;
197-
const promisify = java.asyncOptions.promisify;
198-
if (typeof promiseSuffix === "string" && typeof promisify === "function") {
197+
if (typeof promiseSuffix === "string") {
199198
const methods = ["newInstance", "callMethod", "callStaticMethod"];
200199
methods.forEach(function (name) {
201-
java[name + promiseSuffix] = promisify(java[name]);
200+
java[name + promiseSuffix] = util.promisify(java[name]);
202201
});
203-
} else if (typeof promiseSuffix === "undefined" && typeof promisify === "undefined") {
204-
// no promises
205-
} else {
206-
throw new Error("In asyncOptions, if either promiseSuffix or promisify is defined, both most be.");
207202
}
208203

209204
if (typeof java.asyncOptions.ifReadOnlySuffix === "string" && java.asyncOptions.ifReadOnlySuffix !== "") {
@@ -273,10 +268,8 @@ java.import = function (name) {
273268
}
274269
}
275270

276-
let promisify = undefined;
277271
let promiseSuffix;
278-
if (java.asyncOptions && java.asyncOptions.promisify) {
279-
promisify = java.asyncOptions.promisify;
272+
if (java.asyncOptions) {
280273
promiseSuffix = java.asyncOptions.promiseSuffix;
281274
}
282275

@@ -297,9 +290,9 @@ java.import = function (name) {
297290
result[asyncName] = callStaticMethod.bind(java, name, methodName);
298291
}
299292

300-
if (promisify && typeof promiseSuffix === "string") {
293+
if (typeof promiseSuffix === "string") {
301294
const promiseName = usableName(methodName + promiseSuffix);
302-
result[promiseName] = promisify(callStaticMethod.bind(java, name, methodName));
295+
result[promiseName] = util.promisify(callStaticMethod.bind(java, name, methodName));
303296
}
304297
}
305298
}

testAsyncOptions/allThreeSuffix.test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ describe("allThreeSuffix", () => {
1212
syncSuffix: "Sync",
1313
asyncSuffix: "Async",
1414
promiseSuffix: "Promise",
15-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
16-
promisify: ((await import("when/node")) as any).lift, // https://github.com/cujojs/when
1715
});
1816
});
1917

testAsyncOptions/clientPBeforeError.test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ describe("clientPBeforeError", () => {
77
{
88
syncSuffix: "Sync",
99
promiseSuffix: "Promise",
10-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
11-
promisify: ((await import("when/node")) as any).lift, // https://github.com/cujojs/when
1210
},
1311
{
1412
beforeInit: async (java) => {

testAsyncOptions/clientPBeforeThrows.test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ describe("clientPBeforeThrows", () => {
77
{
88
syncSuffix: "Sync",
99
promiseSuffix: "Promise",
10-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
11-
promisify: ((await import("when/node")) as any).lift, // https://github.com/cujojs/when
1210
},
1311
{
1412
beforeInit: async (java) => {

testAsyncOptions/defactoPlusPromise.test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ describe("defactoPlusPromise", () => {
1313
syncSuffix: "Sync",
1414
asyncSuffix: "",
1515
promiseSuffix: "Promise",
16-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
17-
promisify: ((await import("when/node")) as any).lift, // https://github.com/cujojs/when
1816
},
1917
{
2018
beforeInit: (java) => {
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { describe, expect, test } from "vitest";
2+
import { getJava } from "../testHelpers";
3+
4+
describe("ensureJvmPromise", () => {
5+
test("calling ensureJvm as a promise", async () => {
6+
await getJava(
7+
{
8+
syncSuffix: "Sync",
9+
asyncSuffix: "",
10+
},
11+
{
12+
beforeInit: async (java) => {
13+
expect(java.isJvmCreated()).toBeFalsy();
14+
await java.ensureJvm();
15+
expect(java.isJvmCreated()).toBeTruthy();
16+
},
17+
}
18+
);
19+
});
20+
});

testAsyncOptions/invalidLaunch.test.ts

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,11 @@ import { describe, expect, test } from "vitest";
22
import { getJava } from "../testHelpers";
33

44
describe("invalidLaunch", () => {
5-
test("calling ensureJvm as a promise when no promisify function supplied", async () => {
6-
await getJava(
7-
{
8-
syncSuffix: "Sync",
9-
asyncSuffix: "",
10-
},
11-
{
12-
beforeInit: (java) => {
13-
expect(java.isJvmCreated()).toBeFalsy();
14-
15-
// First show that if asyncOptions.promisify is undefined, using the promise variant of ensureJvm throws an error.
16-
expect(() => {
17-
void java.ensureJvm();
18-
}).toThrow(/requires its one argument to be a callback function/);
19-
20-
expect(java.isJvmCreated()).toBeFalsy();
21-
},
22-
}
23-
);
24-
});
25-
265
test("callbackNotAFunction", async () => {
276
await getJava(
287
{
298
syncSuffix: "",
309
promiseSuffix: "P",
31-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
32-
promisify: ((await import("when/node")) as any).lift, // https://github.com/cujojs/when
3310
},
3411
{
3512
beforeInit: (java) => {
@@ -51,8 +28,6 @@ describe("invalidLaunch", () => {
5128
{
5229
syncSuffix: "",
5330
promiseSuffix: "P",
54-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
55-
promisify: ((await import("when/node")) as any).lift, // https://github.com/cujojs/when
5631
},
5732
{
5833
beforeInit: async (java) => {

testAsyncOptions/noAsync.test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ describe("noAsync", () => {
1212
{
1313
syncSuffix: "Sync",
1414
promiseSuffix: "Promise",
15-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
16-
promisify: ((await import("when/node")) as any).lift,
1715
},
1816
{
1917
beforeInit: (java) => {

testAsyncOptions/syncDefaultPlusPromise.test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ describe("syncDefaultPlusPromise", () => {
1212
java = await getJava({
1313
syncSuffix: "",
1414
promiseSuffix: "P",
15-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
16-
promisify: ((await import("when/node")) as any).lift, // https://github.com/cujojs/when
1715
});
1816
});
1917

0 commit comments

Comments
 (0)