commons-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Martin Sandiford (Created) (JIRA)" <>
Subject [jira] [Created] (EXEC-63) Race condition in DefaultExecutor#execute(cmd, handler)
Date Thu, 23 Feb 2012 00:21:48 GMT
Race condition in DefaultExecutor#execute(cmd, handler)

                 Key: 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 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) {

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:!default.jspa
For more information on JIRA, see:


View raw message