"Write dead end" IOException when using Piped streams w/PumpStreamHandler
-------------------------------------------------------------------------

                 Key: EXEC-49
                 URL: https://issues.apache.org/jira/browse/EXEC-49
             Project: Commons Exec
          Issue Type: Bug
    Affects Versions: 1.1
         Environment: RHEL 5, Ubuntu 10.04
            Reporter: Kevin Telford
            Priority: Minor


{code:title=Sad Trombone}
java.io.IOException: Write end dead
        at java.io.PipedInputStream.read(PipedInputStream.java:294)
        at com.mycompany.commonsexecrunner.App.main(App.java:48)
{code}

I came across this issue when I was 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.

{code:title=Throws IOException}
    public static void main(String[] args) {

        System.out.println("Hello world");

        CommandLine cl = CommandLine.parse("/bin/ls");
        cl.addArgument("/opt");

        DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler();
        PipedOutputStream stdout = new PipedOutputStream();
        PumpStreamHandler psh = new PumpStreamHandler(stdout);
        Executor exec = new DefaultExecutor();
        exec.setStreamHandler(psh);

        try {
            System.out.println("Preparing to execute process - commandLine=" + 
cl.toString());
            exec.execute(cl, handler);
            System.out.println("Process spun off successfully - process=" + 
cl.getExecutable());
        } catch (ExecuteException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        
        PipedInputStream pis = null;
        try {
            pis = new PipedInputStream(stdout);
        } catch (IOException ex) {
            ex.printStackTrace();
        }

        int x;
        try {
            while ((x = pis.read()) >= 0) {
                System.out.println("pis.available() " + pis.available());
                System.out.println("x " + x);
            }
        } catch  (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                pis.close();
            } catch (IOException ex) {
            }
        }

        System.out.println("Goodbye world");

    }
{code}

I was able to mitigate the error by modifying the createProcessOutputPump() 
method in the PumpStreamHandler class to accept the boolean value 
closeWhenExhausted, like was used for the setProcessInputStream() method.
{code}
protected void createProcessOutputPump(final InputStream is, final OutputStream 
os, final boolean closeWhenExhausted) {
    outputThread = createPump(is, os, closeWhenExhausted);
}
{code}

This solution isn't implemented in the best way because in the end you have to 
pass a boolean value all the way down and it's kind of messy, but its a start.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to