node-java icon indicating copy to clipboard operation
node-java copied to clipboard

The process refuses to quit.

Open UchihaYuki opened this issue 4 years ago • 7 comments

I'm using java:0.12.2, and running on Windows 10. After executing the following code:

const java = require("java")
const ArrayList = java.import("java.util.ArrayList");
console.log(new ArrayList().sizeSync())

The process doesn't exit. Is there a java.destroy() or something?

UchihaYuki avatar Nov 11 '21 14:11 UchihaYuki

I am having the same issue, this is my example (but having issue with much bigger codebase, this is just my minimal example).

const java = require('java');
const out = java.getStaticFieldValue("java.lang.System", "out");
java.callMethodSync(out, "println", "Hello from JAVA!");

If I use npm install [email protected] everything is OK, but with version [email protected] is doesn't quit the process. Tested with

  • Win10/java 1.8.0_201
  • node:14.19.1 + openjdk 1.8.0_322 + debian9 (container)
  • node:16.15.0 + openjdk 11.0.15 + debian10 (container)
>npm install [email protected] --save-dev
>node test.js
Hello from JAVA!
>npm install [email protected] --save-dev
>node test.js
Hello from JAVA!
....

jjuzna avatar May 12 '22 13:05 jjuzna

A single line example

var java = require('java');

And the issue can be recreated when following Docker section of readme.md

jjuzna avatar May 13 '22 11:05 jjuzna

I did some more research. The root problem is adding uv_async_init line in commit https://github.com/joeferner/node-java/commit/bc557ad101909990e2d4c

This call creates and runs handler that never quits so the node process continues to run. Previous version placed callbacks directly to queue that was processed by main thread. The commit message is very useful and explains why this was done this way, but unfortunately there is no "exit" event.

The only workaround that I found is scorched earth approach - call process.exit(0) - this will kill all - including other ongoing tasks (Promise...) - and exit.

jjuzna avatar May 17 '22 15:05 jjuzna

As a workaround, you can create a fork process and then kills it. This would prevent crashing the main process.

Tomas2D avatar May 18 '22 08:05 Tomas2D

I've created a fork (and merge request) that adds stop() function to java object. That function closes handle used in loop spawned by uv_async_init and after that Node process can quit normally.

const java = require('java');
const out = java.getStaticFieldValue("java.lang.System", "out");
java.callMethodSync(out, "println", "Hello from JAVA!");
java.stop();

jjuzna avatar May 18 '22 10:05 jjuzna