5

I want to call node js function from java:

here is my hello.js javascript code:

function myFun(param)
{
     console.log("hello"+param);
}

here is my java code:

public static void main(String[] args) throws IOException {
  Process process = new ProcessBuilder("C:\\Program Files\\nodejs\\node.exe","hello.js").start();
  InputStream is = process.getInputStream();
  InputStreamReader isr = new InputStreamReader(is);
  BufferedReader br = new BufferedReader(isr);
  String line;
  
  
  while ((line = br.readLine()) != null) {
    System.out.println(line);
  }
    }

With this java code i am able to execute hello.js file but i want to call myFun function and set the parameters in this function from java code .. is it possible to do this.

2
  • 2
    You can pass command line arguments to the node program when you start it and have the startup code do something based on those command line arguments. Or you could start a server and communicate with that server from your Java. Or you could send it something via stdin. But, your Java has no direct access to the internals of the node program so you have to use one of the existing communication mechanisms or build a new communication mechanism yourself. Commented Jul 12, 2020 at 7:02
  • Can I do with with a process builder? Commented Jul 12, 2020 at 7:24

3 Answers 3

3

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.

Sign up to request clarification or add additional context in comments.

Comments

1

It's not that easy. You have a few possible methods to do that:

  1. Use JNI-Bindings to V8 (Node.js is just V8 with a big library and some glue).
  2. Use ProcessBuilder and pass the arguments.
  3. (It's not exactly what you asked for) Use a Javascript-Engine written in Java (GraalVM)

Pros/Cons

  1. Has the advantage, that it may give you a lot of control (==>More flexible), but writing JNI is hard, error-prone and time-consuming.
  2. is the most simple solution, but not that flexible.
  3. is maybe another solution, that can be superior to 1. (No need to ship native libraries) and 2. (Very fragile, as you need a specific location for node.exe).

Comments

0

I would suggest looking into https://github.com/caoccao/Javet, it allows you to embed a node.js runtime into a java application.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.