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:
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.