commons-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Kevin Telford (JIRA)" <j...@apache.org>
Subject [jira] Created: (EXEC-49) "Write dead end" IOException when using Piped streams w/PumpStreamHandler
Date Wed, 13 Oct 2010 00:40:32 GMT
"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.


Mime
View raw message