0

I use a ProcessBuilder to run system command from java. The system command may ask input data from user. Program failed when the system command asks input data from user for multiple times. Example of running such a command from command-line directly:

>test-input
Continue? Y/N
y
Entered y
Again: Continue? Y/N
y
Entered y

If I use my ProcessBuilder based program to run "test-input", it either hangs or failed to take input for a second time. Here is the code of reading/writing logic. Read from input stream (Exception handling and stream close logic is omitted)

ProcessBuilder pb = new ProcessBuilder(cmdList);
pb.redirectErrorStream(true);
pb.directory(new File("some-test-dir"));
process = pb.start();
InputStream is = process.getInputStream();
int value = -1;
while ( (value = is.read()) != -1) {
    reader.append((char)value);
}
int result = process.waitFor();

Write to output stream:

public void write(String s) {
    OutputStream os = null;
    try {
        os = process.getOutputStream();
        os.write(s.getBytes(Charset.forName("UTF-8")));
    }
    catch (IOException e) {
        //...
    }
    finally {
        // Problematic
        os.close();
    }
}

The problem occurred at the line os.close(). If I put it there, the output stream is closed after the first input data is processed, thus it cannot be re-opened and program cannot take the second input data. If I do not close the output stream, then program hangs there as is.read() gets blocked forever. How to solve this issue? thanks

CMZS
  • 601
  • 6
  • 21
  • 1
    Don’t keep calling process.getOutputStream(). Call `new OuptutStreamWriter(process.getOutputStream())` once per process and use that. Call the writer’s `flush()` method after each write. (Not directly related: it is incorrect to assume one byte is one character. Wrap your process’s InputStream in an InputStreamReader and use the InputStreamReader’s read method.) – VGR Dec 12 '16 at 18:42
  • thanks for pointing out the relationship between one byte and one character – CMZS Dec 15 '16 at 19:21

1 Answers1

0

Problem is fixed by writing a new line character for each input, as described in: Writing to InputStream of a Java Process

os.write(s.getBytes(Charset.forName("UTF-8")));
os.write('\n');
os.flush();
Community
  • 1
  • 1
CMZS
  • 601
  • 6
  • 21