You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "Marcono1234 (Jira)" <ji...@apache.org> on 2024/01/08 22:24:00 UTC

[jira] [Updated] (EXEC-122) PumpStreamHandler(OutputStream) constructor relies on stream being thread-safe

     [ https://issues.apache.org/jira/browse/EXEC-122?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Marcono1234 updated EXEC-122:
-----------------------------
    Summary: PumpStreamHandler(OutputStream) constructor relies on stream being thread-safe  (was: PumpStreamHandler(OutputStream) relies on stream being thread-safe)

> PumpStreamHandler(OutputStream) constructor relies on stream being thread-safe
> ------------------------------------------------------------------------------
>
>                 Key: EXEC-122
>                 URL: https://issues.apache.org/jira/browse/EXEC-122
>             Project: Commons Exec
>          Issue Type: Bug
>    Affects Versions: 1.4.0
>            Reporter: Marcono1234
>            Priority: Minor
>
> h3. Description
> The constructor {{org.apache.commons.exec.PumpStreamHandler.PumpStreamHandler(OutputStream)}} which uses the {{OutputStream}} for both 'out' and 'err' currently does not perform any synchronization, so potentially two threads are writing at the same time to {{OutputStream}}.
> (This also applies to the other {{PumpStreamHandler}} constructor overloads in case the user manually provides the same {{OutputStream}} instance both as 'out' and 'err').
> This is error-prone because not all {{OutputStream}} implementations are thread-safe, and the user might not be aware of this behavior.
> So it would be good to either:
> - Mention in the {{PumpStreamHandler(OutputStream)}} documentation (and possibly for the other constructor overloads as well, if the same stream instance is used), that the {{OutputStream}} has to be thread-safe
> - Or, {{PumpStreamHandler}} (or {{StreamPumper}}) should perform synchronization, for example if the same stream instance is used by wrapping it in a custom synchronizing {{OutputStream}}
> (though maybe that is not desired if the stream is already thread-safe, e.g. {{Files.newOutputStream}})
> h3. Example
> Run this code snippet:
> {code}
> OutputStream out = new OutputStream() {
>     @Override
>     public void write(int b) throws IOException {
>         System.out.println(Thread.currentThread().getName());
>     }
> };
> PumpStreamHandler p = new PumpStreamHandler(out);
> p.setProcessOutputStream(new ByteArrayInputStream(new byte[1]));
> p.setProcessErrorStream(new ByteArrayInputStream(new byte[1]));
> p.start();
> Thread.sleep(1000);
> {code}
> You will see that it prints two different thread sames. If you place a breakpoint at the {{println}} you will also see that no synchronization is performed, and the calls happen concurrently.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)