I am trying to solve interaction with command line process using Apache Commons exec. I'm stuck with following code:
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayOutputStream ins = new ByteArrayOutputStream();
OutputStreamWriter ow = new OutputStreamWriter(ins);
BufferedWriter writer = new BufferedWriter(ow);
ByteArrayInputStream in = new ByteArrayInputStream(ins.toByteArray());
PumpStreamHandler psh = new PumpStreamHandler(out, null, in);
CommandLine cl = CommandLine.parse(initProcess);
DefaultExecutor exec = new DefaultExecutor();
DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();
exec.setStreamHandler(psh);
try {
exec.execute(cl, resultHandler);
int i = 0;
while (true) {
String o = out.toString();
if (!o.trim().isEmpty()) {
System.out.println(o);
out.reset();
}
// --- PROBLEM start ---
if (i == 3) {
writer.write(internalProcessCommand);
// string with or without trailing \n, both tested
writer.flush();
writer.close();
// tested even ins.write(internalProcessCommand.getBytes())
}
// --- PROBLEM end ---
Thread.sleep(3000);
i++;
}
} catch (ExecuteException e) {
System.err.println(e.getMessage());
}
I hope my code is clear. I continuously read out
and print it after 3 seconds while clearing stream. Problem is input to in
passed to PumpStreamHandler
. I need to pass process commands from code itself, continuously and dynamically as if I was interacting with process through CLI. When I simply use System.in
as PumpStreamHandler
argument, I can write process commands from console fine. How can I manage to have same result passing strings from code?
Edit:
I also tried to connect PipedInputStream
receiving data from PipedOutputStream
, but it seems that data can be read only after closing PipedOutputStream
which makes it un-reusable thus I can't achieve interactivity.
Edit 2: Solved myself. Solution in answer below. Howgh. :-)
Okay, I solved this using built-in tools rather than external libraries. I was able to achieve my goal thanks to independant thread which reads
Process
'InputStream
:StreamReader: