commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sgoes...@apache.org
Subject svn commit: r1031721 - in /commons/proper/exec/trunk/src: changes/changes.xml main/java/org/apache/commons/exec/PumpStreamHandler.java test/java/org/apache/commons/exec/DefaultExecutorTest.java
Date Fri, 05 Nov 2010 19:07:57 GMT
Author: sgoeschl
Date: Fri Nov  5 19:07:57 2010
New Revision: 1031721

URL: http://svn.apache.org/viewvc?rev=1031721&view=rev
Log:
[exec-49] Avoid getting "Write dead end" IOException when using Piped streams w/PumpStreamHandler.
When seing an PipedOutputStream we close it automatically.

Modified:
    commons/proper/exec/trunk/src/changes/changes.xml
    commons/proper/exec/trunk/src/main/java/org/apache/commons/exec/PumpStreamHandler.java
    commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java

Modified: commons/proper/exec/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/exec/trunk/src/changes/changes.xml?rev=1031721&r1=1031720&r2=1031721&view=diff
==============================================================================
--- commons/proper/exec/trunk/src/changes/changes.xml (original)
+++ commons/proper/exec/trunk/src/changes/changes.xml Fri Nov  5 19:07:57 2010
@@ -23,6 +23,13 @@
         <author email="sgoeschl@apache.org">Siegfried Goeschl</author>
     </properties>
     <body>
+        <release version="1.2" date="2010-11-05" description="Maintenance Release">
+            <action dev="sgoeschl" type="fix" date="2010-10-05" issue="EXEC-49" due-to="Kevin
Telford">
+                "Write dead end" IOException when using Piped streams w/PumpStreamHandler.
+                When encountering a PipedOutputStream we will automatically close it to avoid
+                the exception.
+            </action>
+        </release>
         <release version="1.1" date="2010-10-08" description="Maintenance Release">
             <action dev="sebb" type="fix" date="2010-10-05" >
                 OpenVMS now uses symbols instead of logicals for environment variables.

Modified: commons/proper/exec/trunk/src/main/java/org/apache/commons/exec/PumpStreamHandler.java
URL: http://svn.apache.org/viewvc/commons/proper/exec/trunk/src/main/java/org/apache/commons/exec/PumpStreamHandler.java?rev=1031721&r1=1031720&r2=1031721&view=diff
==============================================================================
--- commons/proper/exec/trunk/src/main/java/org/apache/commons/exec/PumpStreamHandler.java
(original)
+++ commons/proper/exec/trunk/src/main/java/org/apache/commons/exec/PumpStreamHandler.java
Fri Nov  5 19:07:57 2010
@@ -23,6 +23,7 @@ import org.apache.commons.exec.util.Debu
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.io.PipedOutputStream;
 
 /**
  * Copies standard output and error of subprocesses to standard output and error
@@ -258,14 +259,17 @@ public class PumpStreamHandler implement
 
     /**
      * Creates a stream pumper to copy the given input stream to the given
-     * output stream.
+     * output stream. When the 'os' is an PipedOutputStream we are closing
+     * 'os' afterwards to avoid an IOException ("Write end dead"). 
      *
      * @param is the input stream to copy from
      * @param os the output stream to copy into
      * @return the stream pumper thread
      */
     protected Thread createPump(final InputStream is, final OutputStream os) {
-        return createPump(is, os, false);
+
+        boolean closeWhenExhausted = (os instanceof PipedOutputStream ? true : false);
+        return createPump(is, os, closeWhenExhausted);
     }
 
     /**

Modified: commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java
URL: http://svn.apache.org/viewvc/commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java?rev=1031721&r1=1031720&r2=1031721&view=diff
==============================================================================
--- commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java
(original)
+++ commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java
Fri Nov  5 19:07:57 2010
@@ -18,20 +18,22 @@
 
 package org.apache.commons.exec;
 
+import junit.framework.TestCase;
+import org.apache.commons.exec.environment.EnvironmentUtils;
+
 import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
 import java.util.HashMap;
 import java.util.Map;
 
-import junit.framework.TestCase;
-import org.apache.commons.exec.environment.EnvironmentUtils;
-
 public class DefaultExecutorTest extends TestCase {
 
     /** Maximum time to wait (15s) */
@@ -937,6 +939,90 @@ public class DefaultExecutorTest extends
         assertFalse("The watchdog is no longer watching any process", watchdog.isWatching());
     }
 
+    /**
+     * Test EXEC-49 (https://issues.apache.org/jira/browse/EXEC-49).
+     *
+     * The issue was detected when trying to capture stdout/stderr with a PipedOutputStream
and
+     * then pass that to a PipedInputStream. The following code will produce the error.
+     * The reason for the error is the PipedOutputStream is not being closed correctly,
+     * causing the PipedInputStream to break.
+     *
+     * @throws Exception the test failed
+     */
+    public void testExec49_1() throws Exception {
+
+        if(OS.isFamilyUnix()) {
+
+            CommandLine cl = CommandLine.parse("/bin/ls");
+            cl.addArgument("/opt");
+
+            Executor exec = new DefaultExecutor();
+
+            // redirect stdout/stderr to pipedOutputStream
+            PipedOutputStream pipedOutputStream = new PipedOutputStream();
+            PumpStreamHandler psh = new PumpStreamHandler(pipedOutputStream);
+            exec.setStreamHandler(psh);
+
+            // start an asynchronous process to enable the main thread
+            System.out.println("Preparing to execute process - commandLine=" + cl.toString());
+            DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler();    
      
+            exec.execute(cl, handler);
+            System.out.println("Process spun off successfully - process=" + cl.getExecutable());
+    
+            int x;
+            PipedInputStream pis = new PipedInputStream(pipedOutputStream);
+            while ((x = pis.read()) >= 0) {
+                System.out.println("pis.available() " + pis.available());
+                System.out.println("x " + x);
+            }
+            pis.close();
+
+            handler.waitFor();
+        }
+    }
+
+    /**
+     * Test EXEC-49 (https://issues.apache.org/jira/browse/EXEC-49).
+     *
+     * The issue was detected when trying to capture stdout with a PipedOutputStream and
+     * then pass that to a PipedInputStream. The following code will produce the error.
+     * The reason for the error is the PipedOutputStream is not being closed correctly,
+     * causing the PipedInputStream to break.
+     *
+     * @throws Exception the test failed
+     */
+    public void testExec49_2() throws Exception {
+
+        if(OS.isFamilyUnix()) {
+
+            CommandLine cl = CommandLine.parse("/bin/ls");
+            cl.addArgument("/opt");
+
+            Executor exec = new DefaultExecutor();
+
+            // redirect only stdout to pipedOutputStream
+            PipedOutputStream pipedOutputStream = new PipedOutputStream();
+            PumpStreamHandler psh = new PumpStreamHandler(pipedOutputStream, new ByteArrayOutputStream());
+            exec.setStreamHandler(psh);
+
+            // start an asynchronous process to enable the main thread
+            System.out.println("Preparing to execute process - commandLine=" + cl.toString());
+            DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler();
+            exec.execute(cl, handler);
+            System.out.println("Process spun off successfully - process=" + cl.getExecutable());
+
+            int x;
+            PipedInputStream pis = new PipedInputStream(pipedOutputStream);
+            while ((x = pis.read()) >= 0) {
+                System.out.println("pis.available() " + pis.available());
+                System.out.println("x " + x);
+            }
+            pis.close();
+
+            handler.waitFor();            
+        }
+    }
+
     // ======================================================================
     // === Long running tests
     // ======================================================================



Mime
View raw message