joeferner / node-java

Bridge API to connect with existing Java APIs.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

The process refuses to quit.

UchihaYuki opened this issue · 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?

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 java@0.12.1 everything is OK, but with version java@0.12.2 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 java@0.12.1 --save-dev
>node test.js
Hello from JAVA!
>npm install java@0.12.2 --save-dev
>node test.js
Hello from JAVA!
....

A single line example

var java = require('java');

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

I did some more research. The root problem is adding uv_async_init line in 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.

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

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();