Home > Net >  Java Process Builder builds the process successfully but when flushing information returns Stream cl
Java Process Builder builds the process successfully but when flushing information returns Stream cl

Time:07-14

Environment Information

OS: Linux( java program running in a docker container)

Java version: 1.8

Node version: 10.22.1

I am trying to create a process from an executable js file with the java ProcessBuilder class like below:

String command = "/node/app/bin/app.js"
final ProcessBuilder pb = new ProcessBuilder(command);
Process process = pb.start();
OutputStream out = process.getOutputStream();
 out.write("\n[:--:]".getBytes());
out.flush();// this line throws the error java.io.IOException: Stream closed

After running the pb.start() the process is created successfully, below is the debug information: enter image description here

The problem is when the out.flush() command which throws an exception when executed. Below is the execution error:

Caused by: java.io.IOException: Stream closed

at java.lang.ProcessBuilder$NullOutputStream.write(ProcessBuilder.java:433) ~[?:1.8.0_292]

at java.io.OutputStream.write(OutputStream.java:116) ~[?:1.8.0_292]

at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82) ~[?:1.8.0_292]

at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140) ~[?:1.8.0_292]

The /node/app/bin/app.js content is like below:

#!/usr/bin/env node
var path = require('path');

var apJsFile = path.resolve(__dirname, '../app.js'); //app.js is working correctly

require(appJsFile);

CodePudding user response:

Your sub-process is likely to be reporting an error and exits while you are writing to the stdin of the sub-process getOutputStream() - hence stream closed. As you are not consuming stdout and stderr streams correctly you haven't had a chance to read any error message.

An easy way to check is to redirect stdout and stderr to a file to inspect afterwards:

pb.redirectOutput(new File("std.out"));          
pb.redirectError(new File("std.err"));
Process process = pb.start();
...
int rc = p.waitFor();

Those files may help you spot the actual problem. The most rebust way to deal with ProcessBuilder is to use consumer tasks in background threads to deal with sub-process stdin, stdout and stderr and wait for these consumers to finish after waitFor(). That will prevent sub-process stall / freeze if I/O is pending on any one of the streams: getOutputStream(), getInputStream() and getErrorStream().

CodePudding user response:

The command /node/app/bin/app.js when executed on my environment directly in linux container was not working. Since pb.start() was not throwing any exception I thought this was not a problem of the command itself because it will have caused the start method to throw an exception.

After fixing the error /node/app/bin/app.js(it was a formatting issue and shebangs was not working properly) then the error caused by out.flush() disappeared.

  • Related