JDK-6481278 : (process) Runtime should provide a real spawning capability
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 6
  • Priority: P4
  • Status: Resolved
  • Resolution: Won't Fix
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2006-10-12
  • Updated: 2013-08-08
  • Resolved: 2013-08-08
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
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.

Comments
Java does not need implicit inheritance for IOE handles and after the JDK-7147084 bug fix that is a user responsibility to avoid setting the inheritance flag in the user's native code. All Java handles, but not IOE for child process, have no the inheritance flag. The IOE handles for child process are treated accurate since the JDK-7147084 bug fix.
08-08-2013

EVALUATION But 6428742 is a defect report, as if the inheritance flag being set one way vs another is "wrong", while this is a request for enhancement, asking for an API to provide increased choice of inheritance semantics.
12-10-2006

EVALUATION Looks like a dup of 6428742: (process) Call CreateProcess with bInheritHandles=FALSE ?
12-10-2006