I have no idea why this is hanging. I'm trying to capture output from a process run through commons-exec, and I continue to hang. I've provided an example program to demonstrate this behavior below.
import java.io.DataInputStream;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import o开发者_如何学JAVArg.apache.commons.exec.ExecuteException;
import org.apache.commons.exec.PumpStreamHandler;
public class test {
public static void main(String[] args) {
String command = "java";
PipedOutputStream output = new PipedOutputStream();
PumpStreamHandler psh = new PumpStreamHandler(output);
CommandLine cl = CommandLine.parse(command);
DefaultExecutor exec = new DefaultExecutor();
DataInputStream is = null;
try {
is = new DataInputStream(new PipedInputStream(output));
exec.setStreamHandler(psh);
exec.execute(cl);
} catch (ExecuteException ex) {
} catch (IOException ex) {
}
System.out.println("huh?");
}
}
According to the javadoc, execute(CommandLine command)
is synchronous, execute(CommandLine command, ExecuteResultHandler handler)
on the other hand is asynchronous.
The command you invoked, java
, produces output to its standard output stream. That stream must be pumped into an input stream by your invoking program. This does not happen in your program.
You have to read the input stream (is
in your code) in a separate thread, because that is how piped streams work. Note that you must start the reading thread before calling execute()
.
See also Capturing large amounts of output from Apache Commons-Exec
According to your other question Streaming output with commons-exec? you expect large data, so you must use the piped streams and cannot use the simpler approach of using a ByteArrayInputStream
as output. The answer you give yourself there, suffers from the same problem as your code here.
精彩评论