commons-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Patrick Strawderman (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (EXEC-102) "Stream closed" error in Java 8 when passing input to processes that don't consume it
Date Wed, 06 Apr 2016 18:43:25 GMT

    [ https://issues.apache.org/jira/browse/EXEC-102?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15228864#comment-15228864
] 

Patrick Strawderman commented on EXEC-102:
------------------------------------------

Pretty sure this is caused by a change made to UnixProcess in JDK 8: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/lang/UNIXProcess.java#561

When the process exits, the out field of the ProcessPipeOutputStream is closed and swapped
with a NullOutputStream, which has a write method that always throws IOException.

Write is called because ProcessPipeOutputStream extends BufferedOutputStream which calls flush()
when its closed (since the stream was never read from, it still has data in its buffer which
it attempts to write out to the underlying stream).

The observed raciness is due to the way the processExited() is called asynchronously by the
processReaperExecutor.

Maybe the IOException should simply be swallowed?

> "Stream closed" error in Java 8 when passing input to processes that don't consume it
> -------------------------------------------------------------------------------------
>
>                 Key: EXEC-102
>                 URL: https://issues.apache.org/jira/browse/EXEC-102
>             Project: Commons Exec
>          Issue Type: Bug
>    Affects Versions: 1.3
>            Reporter: Chris Price
>            Assignee: Siegfried Goeschl
>
> When trying to pass an InputStream to a process (i.e. for it to be used as STDIN), I
am getting an IOException in Java 8 that I did not get in Java 7.
> We have observed this behavior with both Oracle JDK8 and OpenJDK8, and on various Red
Hat Linux and Ubuntu Linux systems, and also on Mac OSX.
> Here is a simple reproducer:
> {code}
> package foo;
> import org.apache.commons.exec.CommandLine;
> import org.apache.commons.exec.DefaultExecutor;
> import org.apache.commons.exec.Executor;
> import org.apache.commons.exec.PumpStreamHandler;
> import java.io.ByteArrayInputStream;
> import java.io.ByteArrayOutputStream;
> import java.io.IOException;
> public class CommonsExecBinTrue {
>     public static void main(String[] args) throws IOException {
>         Executor exec = new DefaultExecutor();
>         CommandLine cl = new CommandLine("/bin/true");
>         String text = "hello";
>         ByteArrayInputStream input =
>                 new ByteArrayInputStream(text.getBytes("UTF-8"));
>         ByteArrayOutputStream output = new ByteArrayOutputStream();
>         exec.setStreamHandler(new PumpStreamHandler(output, null, input));
>         exec.execute(cl);
>         System.out.println("result: " + output.toString("UTF-8"));
>     }
> }
> {code}
> This program would work fine in Java 7, but in Java 8 it fails with this stack trace:
> {code}
> Exception in thread "main" java.io.IOException: Stream closed
> 	at java.lang.ProcessBuilder$NullOutputStream.write(ProcessBuilder.java:433)
> 	at java.io.OutputStream.write(OutputStream.java:116)
> 	at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
> 	at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
> 	at java.io.FilterOutputStream.close(FilterOutputStream.java:158)
> 	at org.apache.commons.exec.DefaultExecutor.closeProcessStreams(DefaultExecutor.java:306)
> 	at org.apache.commons.exec.DefaultExecutor.executeInternal(DefaultExecutor.java:387)
> 	at org.apache.commons.exec.DefaultExecutor.execute(DefaultExecutor.java:166)
> 	at org.apache.commons.exec.DefaultExecutor.execute(DefaultExecutor.java:153)
> 	at foo.CommonsExecBinTrue.main(CommonsExecBinTrue.java:27)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
> 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> 	at java.lang.reflect.Method.invoke(Method.java:497)
> 	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
> {code}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Mime
View raw message