15

I have a Java program that I normally start from command line. After starting from command line, the java program keeps running forever until Ctrl+C is pressed to quit it or kill command from another script. The Java program outputs error messages if any to the console.

Now I want to develop express based NodeJs web application. When the user clicks on a link (Run) , the click handler will invoke Ajax request which will cause the backend NodeJs script to run this Java program if it is not already running. Another link (Stop) will make Ajax request to stop this Java program.

How this can be achieved? Answer with sample code will be most useful.

Also there is a requirement: if this NodeJs web application is terminated, the Java program that was started by it, keeps running i.e. it is not dependent on NodeJs web application.

rjc
  • 2,885
  • 8
  • 32
  • 40
  • Is this not a duplicate of : http://stackoverflow.com/questions/8389974/how-to-run-commands-via-nodejs-child-process ? – Frederic Close Sep 15 '13 at 18:13
  • 1
    The question this was closed as a duplicate of doesn't seem like a great match; this has an answer with sample code, while the other just discusses the tradeoffs between two approaches without saying how to do either. I'm voting to reopen. – Ryan M Dec 01 '20 at 02:43
  • I'm voting to reopen as well. If anything, the target should be closed as a duplicate of this post. – cigien Dec 01 '20 at 02:47

3 Answers3

14

You can start a child process, and send a kill signal when you don't need it.

var spawn = require('child_process').spawn;
var child = spawn('java', ['params1', 'param2']);

To kill the application, or to simulate a CTRL+C, send a signal:

// control + c is an interrupt signal
child.kill('SIGINT');

// or send from the main process
process.kill(child.pid, 'SIGINT');

If you're going to run the application detached, you should probably write the PID somewhere. To run the application detached, run it like this:

var fs = require('fs');
var out = fs.openSync('./out.log', 'a');
var err = fs.openSync('./out.log', 'a');

var child = spawn('java', [], {
  detached: true,
  stdio: [ 'ignore', out, err ]
});
child.unref();

This spawns a child process whose I/O streams aren't associated with the parent process.

hexacyanide
  • 88,222
  • 31
  • 159
  • 162
  • Very helpful, thanks! I was not sure to use exec or spawn as I thought spawn will not create a new process but something that is owned by the process in which nodejs code is running. But now it looks like the detach feature in spawn will take care of this – rjc Sep 15 '13 at 20:11
  • Is there a way to asynchronously listen for someone writing to stdin from the java application side? – endy Dec 22 '15 at 14:44
  • @endy Do you mean something like [this](http://stackoverflow.com/questions/4260942/how-to-asynchronously-read-stdin)? – hexacyanide Dec 22 '15 at 18:20
  • In my usecase I used Node.js as a tool which just needed to call some Java utility and wait for answer. In such case `execFileSync` is more suitable than `spawn` (also the method returned stdout as Node.js Buffer which had to be converted into string). – Tomáš Záluský Feb 13 '18 at 08:14
  • @TomášZáluský I'm interested on the method, do you have an example? Thanks – Weijing Jay Lin Apr 06 '18 at 17:11
  • @WeijingJayLin var svgOutput = execFileSync("java", ["-cp", "some-svg-tool.jar", "SomeClass", someInput], {cwd : "/"}); if (Buffer.isBuffer(svgOutput)) {svgOutput = svgOutput.toString();} – Tomáš Záluský Apr 09 '18 at 06:11
  • Very helpful, but one question. the opened "out.log" file needs to be closed by the nodejs program ? If not, then I could not delete those files even after the java process exited. – Indrajit Kanjilal Sep 29 '20 at 04:46
2

You can simply call a java command , with classpath & arguments, using module node-java-caller

Nicolas Vuillamy
  • 564
  • 7
  • 14
0

Normally spawned child process would not end even when the parent process exits. To kill the child process, the child process pid need to be recorded somewhere (in a file to allow the value to exist even when the parent process exits) and the same can be used to kill the child process when required.

  • This is not true for node.js. You have to pass ` detached: true` so the child process would not exit with the parent. – sean Nov 10 '20 at 14:11