You can use GraalVM to call node.js function from java.
GraalVM offers you a polyglot runtime and the distribution includes both a JDK and a node.
You can execute JavaScript from Java, embedding the JavaScript context in your Java program, like this:
import org.graalvm.polyglot.*;
import org.graalvm.polyglot.proxy.*;
public class HelloPolyglot {
static String JS_CODE = "(function myFun(param){console.log('hello '+param);})";
public static void main(String[] args) {
System.out.println("Hello Java!");
try (Context context = Context.create()) {
Value value = context.eval("js", JS_CODE);
value.execute(args[0]);
}
}
}
Note the () wrapping the function definition, I just want it to return the function immediately there. You can use other ways too, not just code in String too, Files, modules, etc.
And run it with GraalVM on the PATH:
❯ javac HelloPolyglot.java
❯ java HelloPolyglot StackOverflow
Hello Java!
hello StackOverflow
While it's not strictly necessary for this question, here's the Javadoc for the Value class so you can use the polyglot values.
This way you can use JavaScript. It won't have the platform capabilities node.js offers like the node event loop, fs access, etc, node is a separate platform and it's tricky to embed that into a JVM process.
What you can do -- is start the node process, which will start the JVM.
Imagine you have an app like app.js
var HelloPolyglot = Java.type("HelloPolyglot");
HelloPolyglot.main(["from node.js"]);
console.log("done");
You can then run (with GraalVM node):
❯ node --jvm --vm.cp=. app.js
Hello Java!
hello from node.js
done
Note that we pass --jvm to start it with the JVM (otherwise there'll be no capabiltiy to do Java), and pass the classpath of the Java program to the node so it knows how to start the JVM properly.
Both node and JVM then run in the same process, and the interop works using the same Value classes as above.