Race condition in DefaultExecutor#execute(cmd, handler)
-------------------------------------------------------
Key: EXEC-63
URL: https://issues.apache.org/jira/browse/EXEC-63
Project: Commons Exec
Issue Type: Bug
Affects Versions: 1.1
Environment: Windows 7/64 bit, JDK 1.6.0_27
Reporter: Martin Sandiford
DefaultExecutor#execute(CommandLine, ExecuteResultHandler) can, and usually
does, return before the target process has actually started. This can result
in a race condition where several asynchronous processes are coupled by
PipedInputStream/PipedOutputStream objects.
The following example shows the issue:
import java.io.*;
import org.apache.commons.exec.*;
public class Borken {
public static int pipe(OutputStream out, OutputStream err, InputStream in,
CommandLine cmd0, CommandLine cmd1)
throws IOException {
PipedInputStream pipeIn = new PipedInputStream();
PipedOutputStream pipeOut = new PipedOutputStream(pipeIn);
DefaultExecutor exec0 = new DefaultExecutor();
exec0.setStreamHandler(new PumpStreamHandler(pipeOut, null, in));
exec0.execute(cmd0, new DefaultExecuteResultHandler());
// If the following line is commented, deadlock occurs
//try { Thread.sleep(100); } catch (InterruptedException e) { }
DefaultExecutor exec1 = new DefaultExecutor();
exec1.setStreamHandler(new PumpStreamHandler(out, err, pipeIn));
return exec1.execute(cmd1);
}
public static void main(String... args) {
CommandLine cmd0 = new
CommandLine("cmd").addArgument("/c").addArgument("dir");
//CommandLine cmd0 = new CommandLine("ls").addArgument("-l");
CommandLine cmd1 = new CommandLine("sort");
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayOutputStream err = new ByteArrayOutputStream();
ByteArrayInputStream in = new ByteArrayInputStream(new byte[0]);
try {
int result = pipe(out, err, in, cmd0, cmd1);
System.out.format("Result code: %d%n", result);
System.out.format("Out: %s%n", out.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
}
One possible solution is to pass in a semaphore object into
DefaultExecutor#executeInternal which is notified once the process is started.
The execute(CommandLine, Map, ExecuteResultHandler) method can then wait on
this before returning.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators:
https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira