Search code examples
javascriptjavanode.jsnode.js-stream

Node.js child.stdin.write doesn't work


when I try to run child process and put to it stdin some text it throws error. here is code of child process:

import java.io.Console;

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("started");

        Console console = System.console();

        while (true) {
            String s = console.readLine();
            System.out.println("Your sentence:" + s);
        }
    }
}

code of script which run this process:

var spawn = require('child_process').spawn;

var child = spawn('java', ['HelloWorld', 'HelloWorld.class']);


child.stdin.setEncoding('utf-8');

child.stdout.pipe(process.stdout);


child.stdin.write("tratata\n");

// child.stdin.end();

it throws:

events.js:161
  throw er; // Unhandled 'error' event
  ^

Error: read ECONNRESET
    at exports._errnoException (util.js:1028:11)
    at Pipe.onread (net.js:572:26)

notice, when I uncomment line with child.stdin.end(); it only ends whithout any reaction


Solution

  • The one thing you need to make the script work was to add:

    process.stdin.pipe(child.stdin);
    

    If you added this before the child.stdin.write, that would solve half the problem. The other half had to do with the Java side. If the java program is not launched from a console by typing java HelloWorld, then Console will return null thus you will get a NullPointerException if you tried to use Console.readLine. To fix, this use BufferedReader instead.

    Change your script to this:

    const spawn = require('child_process').spawn;
    const child = spawn('java', ['HelloWorld'], {
        stdio: ['pipe', process.stdout, process.stderr]
    });
    
    process.stdin.pipe(child.stdin);
    setTimeout(() => {
        child.stdin.write('tratata\n');
    }, 1000);
    

    Then change your java code to this:

    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    
    import java.io.IOException;
    
    public class HelloWorld {
        public static void main(String[] args) throws IOException {
            System.out.println("started");
    
            try(BufferedReader console = new BufferedReader(new InputStreamReader(System.in))) {
                for (String line = console.readLine(); line != null; line = console.readLine()) {
                    System.out.printf("Your sentence: %s\n", line);
                }
            }
    
        }
    }
    

    See: