[
https://issues.apache.org/jira/browse/EXEC-63?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13217795#comment-13217795
]
Martin Sandiford commented on EXEC-63:
--------------------------------------
Patch for test case from https://github.com/msandiford/commons-exec commit
4c2f449dd5605975d38a2c686dec3c00b7414eee
{code:title=test-case.diff|borderStyle=solid}
--- a/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java
+++ b/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java
@@ -1094,6 +1094,49 @@ public class DefaultExecutorTest extends TestCase {
assertTrue("Not a single process was killed by the watch dog",
watchdogKilledProcessCounter > 0);
}
+
+ /**
+ * Test EXEC-63 (https://issues.apache.org/jira/browse/EXEC-63).
+ *
+ * Frequent deadlock when constructing a command pipe chain.
+ * Please note that a successful test is no proof that the issues was
fixed.
+ *
+ * @throws IOException the test failed
+ */
+ public void testExec_63() throws IOException {
+ CommandLine cmd0;
+ CommandLine cmd1;
+ if (OS.isFamilyUnix()) {
+ cmd0 = new CommandLine("ls").addArgument("-l");
+ cmd1 = new CommandLine("sort");
+ } else if (OS.isFamilyWindows()) {
+ cmd0 = new CommandLine("cmd").addArgument("/c").addArgument("dir");
+ cmd1 = new CommandLine("sort");
+ } else {
+ System.err.println("The test 'testExec_63' does not support the
following OS : " + System.getProperty("os.name"));
+ return;
+ }
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ByteArrayOutputStream err = new ByteArrayOutputStream();
+ ByteArrayInputStream in = new ByteArrayInputStream(new byte[0]);
+ PipedInputStream pipeIn = new PipedInputStream();
+ PipedOutputStream pipeOut = new PipedOutputStream(pipeIn);
+ DefaultExecutor exec0 = new DefaultExecutor();
+ ExecuteWatchdog watchdog0 = new ExecuteWatchdog(5000);
+ exec0.setWatchdog(watchdog0);
+ exec0.setStreamHandler(new PumpStreamHandler(pipeOut, null, in));
+ exec0.execute(cmd0, new DefaultExecuteResultHandler());
+
+ DefaultExecutor exec1 = new DefaultExecutor();
+ ExecuteWatchdog watchdog1 = new ExecuteWatchdog(5000);
+ exec1.setWatchdog(watchdog1);
+ exec1.setStreamHandler(new PumpStreamHandler(out, err, pipeIn));
+ int result = exec1.execute(cmd1);
+ assertTrue("Command exited with status 0", result == 0);
+ assertTrue("Output was as expected", out.toString().length() > 500);
+ assertEquals("No errors were output", err.toString().trim(), "");
+ }
+
// ======================================================================
// === Long running tests
// ======================================================================
{code}
> 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
> Labels: deadlock
> Original Estimate: 24h
> Remaining Estimate: 24h
>
> {{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:
> {code:title=Borken.java|borderStyle=solid}
> 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();
> }
> }
> }
> {code}
> 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