Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-5101298

(process) "IOException: Stream closed" if more data sent after Process.destroy

XMLWordPrintable

    • Cause Known
    • x86
    • linux

        Name: gm110360 Date: 09/13/2004


        FULL PRODUCT VERSION :
        java version "1.5.0-rc"
        Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-rc-b63)
        Java HotSpot(TM) Client VM (build 1.5.0-rc-b63, mixed mode, sharing)

        ADDITIONAL OS VERSION INFORMATION :
        Linux melanie 2.4.9-e.12smp #1 SMP Tue Feb 11 02:24:10 EST 2003 i686 unknown (Red Hat Enterprise Edition)
        Also happens on SuSE Linux 8.1 with Kernel 2.6.7

        A DESCRIPTION OF THE PROBLEM :
        While reading stdout of a native process, an "IOException: Stream closed" is thrown if the process writes some more characters to stdout after Process.destroy() has been called. It is not possible to read until the end of the stream.
        If a process does not write any data to stdout at the moment Process.destroy() is called, the exception is not thrown.

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        Please place the class "ProcessTest" and the shell script "sigtrap.sh" in a directory and execute the class.
        It should execute the shell script for 3 sec, read its stdout and print it to the console, and then terminate the process by calling destroy().

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        I would expect the class to print three lines read from stdout of the script and then the line "trapped SIGTERM".
        This actually happens on HP-UX 11.11 (with Java version 1.4.0).
        ACTUAL -
        Instead of printing "trapped SIGTERM", an "IOException: Stream closed" is thrown. If line 7 in sigtrap.sh is commented out, no data will be written to stdout by the process when it is terminated, and the exception will not occur.

        This is what I think what happens: When destroy() is called on a Process, its input, output and error streams are closed immediately, so that it is not possible to read until the end of the streams without getting an IOException. If the streams are empty at the moment where the process is destroyed, the exception does not occur because the end of the stream(s) was reached before they are closed.

        ERROR MESSAGES/STACK TRACES THAT OCCUR :
        Process stdout: Waiting for signal...0
        Process stdout: Waiting for signal...1
        Process stdout: Waiting for signal...2
        java.io.IOException: Stream closed
                at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:145)
                at java.io.BufferedInputStream.read1(BufferedInputStream.java:253)
                at java.io.BufferedInputStream.read(BufferedInputStream.java:313)
                at sun.nio.cs.StreamDecoder$CharsetSD.readBytes(StreamDecoder.java:411)
                at sun.nio.cs.StreamDecoder$CharsetSD.implRead(StreamDecoder.java:453)
                at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:183)
                at java.io.InputStreamReader.read(InputStreamReader.java:167)
                at java.io.BufferedReader.fill(BufferedReader.java:136)
                at java.io.BufferedReader.readLine(BufferedReader.java:299)
                at java.io.BufferedReader.readLine(BufferedReader.java:362)
                at ProcessTest$1.run(ProcessTest.java:19)

        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        === BEGIN ProcessTest.java ===
        import java.io.*;

        public class ProcessTest {

          public static void main(String[] args) {
            Process p = null;
            try {
              p = Runtime.getRuntime().exec("./sigtrap.sh");
            }
            catch(IOException ioe) {
              ioe.printStackTrace();
            }

            final BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));

            Thread t = new Thread() {
              public void run() {
                try {
                  for(String line = null; (line = br.readLine()) != null;) {
                    System.out.println("Process stdout: " + line);
                  }
                }
                catch(IOException ioe) {
                  ioe.printStackTrace();
                }
              }
            };
            t.start();

            try {
              Thread.sleep(3000);
            }
            catch(Exception e) {}
            p.destroy();
          }
        }
        === END ProcessTest.java ===

        === BEGIN sigtrap.sh ===
        #!/bin/bash
        # sigtrap.sh

        trap trappedTerm 15

        function trappedTerm {
          echo "trapped SIGTERM"
          exit
        }

        COUNTER=0;
        while(true)
          do
          echo "Waiting for signal...$COUNTER" | tee -a out.txt
          sleep 1
          let COUNTER=$COUNTER+1
        done
        === END sigtrap.sh ===
        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
        I have not found a workaround. I am not even sure if this actually is a bug or just a user error. But as this problem does not occur on HP-UX (and maybe also other UNIXes), I think it might be a bug.

        Release Regression From : 1.4.2
        The above release value was the last known release where this
        bug was known to work. Since then there has been a regression.

        (Incident Review ID: 305485)
        ======================================================================

              Unassigned Unassigned
              gmanwanisunw Girish Manwani (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Created:
                Updated:
                Imported:
                Indexed: