System.err / System.out closed prematurely

XMLWordPrintable

      ADDITIONAL SYSTEM INFORMATION :
      Ubuntu 24.04.2 LTS (likely other Linux OSes).
      Linux host 6.6.87.2-microsoft-standard-WSL2 #1 SMP PREEMPT_DYNAMIC Thu Jun 5 18:30:46 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux

      A DESCRIPTION OF THE PROBLEM :
      a Process has its streams prematurely closed during a graceful termination

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      create Shutdown.java with the contents from the "test case code" below then `javac ShutDown` && `java ShutDown`

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The logged output contains `ShutdownHook called`
      ACTUAL -
      the output is not present

      ---------- BEGIN SOURCE ----------
      import java.io.IOException;
      import java.io.InputStream;
      import java.io.PrintStream;
      import java.util.concurrent.TimeUnit;

      public class ShutDown {

          public static Thread thread;
          public static volatile boolean stopped = false;

          public static void main(String[] args) throws IOException, InterruptedException {
              if (args.length == 0) {
                  ProcessBuilder pb = new ProcessBuilder();
                  pb.command("java", "ShutDown", "anything");
                  System.err.println("Starting sub process");
                  Process p = pb.start();

                  new Thread(new StreamGobler(p.getInputStream(), System.out)).start();
                  new Thread(new StreamGobler(p.getErrorStream(), System.err)).start();
                  Thread.sleep(10_000);
                  System.err.println("destroying sub process");
                  p.destroy();
                  boolean exited = p.waitFor(10, TimeUnit.SECONDS);
                  if (exited) {
                      System.out.println("process exited with code:" + p.exitValue());
                  } else {
                      System.err.println("process failed to be killed");
                  }
              } else {
                  Thread t = new Thread(() -> {
                      while (!stopped) {
                          System.out.print(".");
                          try {
                              Thread.sleep(100);
                          } catch (InterruptedException e) {
                          }
                      }
                      System.out.println("Stopped");
                  });
                  System.err.println("adding shutdown hook");
                  Runtime.getRuntime().addShutdownHook(new Thread(() -> {
                      System.err.println("ShutdownHook called");
                      System.err.flush();
                      stopped = true;
                      Runtime.getRuntime().halt(22);
                  }));
                  t.start();
              }
          }

          static class StreamGobler implements Runnable {
              private final InputStream is;
              private final PrintStream output;

              public StreamGobler(InputStream is, PrintStream output) {
                  this.is = is;
                  this.output = output;
              }

              @Override
              public void run() {
                  try {
                      int data = is.read();
                      while (data != -1) {
                          output.print((char) data);
                          data = is.read();
                      }
                      System.err.println("End of Stream");
                  } catch (IOException e) {
                      System.err.println("oopps " + e);
                  }
              }
          }
      }

      ---------- END SOURCE ----------

            Assignee:
            Roger Riggs
            Reporter:
            Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated: