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

(process) Runtime should provide a real spawning capability

    Details

    • Type: Enhancement
    • Status: Resolved
    • Priority: P4
    • Resolution: Won't Fix
    • Affects Version/s: 6
    • Fix Version/s: None
    • Component/s: core-libs
    • Labels:
    • Subcomponent:
    • CPU:
      x86
    • OS:
      windows_xp

      Description

      A DESCRIPTION OF THE REQUEST :
      On Windows, the current java.lan.Runtime.exec() function calls the CreateProcess with the bInheritHandles flag set to TRUE. This mean that handles such as those used by standard inputs and outputs are shared by the whole tree of processes that have been spawned with the bInheritHandles flag set to TRUE. This can lead to problem such as the one in thread http://forum.java.sun.com/thread.jspa?threadID=772669 in the Java Developer's forum.

      JUSTIFICATION :
      This can lead to problem such as this: a java process p1 execs a Java process p2 and read I/O from that process. The Java process p2 then execs a third process p3 and returns. The process p1 blocks on reading I/O until process p3 exits.

      See the problem demonstrated in thread http://forum.java.sun.com/thread.jspa?threadID=772669 in the Java Developer's forum.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The API should provide a way to spawn a completely detached process that in the case of Windows would call CreateProcess with the bInheritHandles flag set to FALSE.
      ACTUAL -
      This is currently not possible because all the exec() API call CreateProcess with bInheritHandles flag set to FALSE.

      ---------- BEGIN SOURCE ----------
      See thread thread http://forum.java.sun.com/thread.jspa?threadID=772669 in the Java Developer's forum.

      Here is the top level script that demonstrate the problem:

      @ECHO OFF
      SETLOCAL & PUSHD %~dp0
      SET JDK_HOME=c:\Program Files\Java\jdk1.6.0
      SET JDK_HOME=c:\j2sdk1.4.2_09
      "%JDK_HOME%\bin\javac" *.java
      ECHO This shows the problem with child Java subprocess that
      ECHO spawns Notepad subsubprocess:
      "%JDK_HOME%\bin\java" -classpath . Exec1
      ECHO Parent Java process exits when Notepad subsubprocess exits.
      POPD & ENDLOCAL



      This is the parent Java process that spawns a Java subprocess and gets status from it: Exec1.java:


      class Exec1 {
          private static Thread streamOutputThread;
          private static Thread streamErrorThread;
       
          public static void main(String[] args) {
              try {
                  Process process = Runtime.getRuntime().exec("Exec2.bat");
                  streamOutputThread = new Thread(new StreamReader(process
                          .getInputStream()));
                  streamOutputThread.setDaemon(true);
                  streamErrorThread = new Thread(new StreamReader(process
                          .getErrorStream()));
                  streamErrorThread.setDaemon(true);
                  streamOutputThread.start();
                  streamErrorThread.start();
                  process.waitFor();
                  streamOutputThread.join();
                  streamErrorThread.join();
              } catch (Exception ex) {
                  ex.printStackTrace();
                  return;
              }
          }
      }



      This is the class that handle the communication: StreamReader.java.


      import java.io.InputStream;
       
      public class StreamReader implements Runnable {
          private static final int SIZE = 128;
          private InputStream is;
       
          public StreamReader(InputStream is) {
              this.is = is;
          }
       
          public void run() {
              final byte[] buf = new byte[SIZE];
       
              int length;
              try {
                  while ((length = is.read(buf)) > 0) {
                      System.out.write(buf, 0, length);
                  }
              } catch (Exception e) {
                  // ignore errors
              }
          }
      }



      This is the intermediate script that show that the Java subprocess has exited: Exec2.bat


      @ECHO OFF
      SETLOCAL & PUSHD %~dp0
      SET JDK_HOME=c:\Program Files\Java\jdk1.6.0
      SET JDK_HOME=c:\j2sdk1.4.2_09
      "%JDK_HOME%\bin\java" -classpath . Exec2
      POPD & ENDLOCAL
      ECHO Child Java subprocess exited.
      ECHO Parent Java process still waiting for spawned Notepad subsubprocess to exit!!!!!



      This is the Java subprocess that spans the Notepad subsubprocess: Exec2.java.


      class Exec2 {
          public static void main(String[] args) {
              try {
                  System.out.println(
                      "Child java subprocess spawning Notepad subsubprocess...");
                  Runtime.getRuntime().exec("Notepad");
              } catch (Exception ex) {
                  ex.printStackTrace();
                  return;
              }
          }
      }

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

      CUSTOMER SUBMITTED WORKAROUND :
      Instead of the Java program calling directly the executable using Runtime.exec(), the temporary workaround was to create a small Windows executable that calls the desired executable using CreateProcess with the bInheritHandles flag set to FALSE. The Java program then was changed to call that intermediate executable instead.

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                uta Alexey Utkin (Inactive)
                Reporter:
                tyao Ting-Yun Ingrid Yao (Inactive)
              • Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:
                  Imported:
                  Indexed: