Java Runtime.exec的奇怪行为

Java Runtime.exec的奇怪行为,java,eclipse,Java,Eclipse,我使用runtime.exec从Java应用程序中启动另一个应用程序。该子程序在调用system.exit(0)时启动没有问题;从父应用程序开始,父JVM将一直运行,直到子程序终止 下面是一个简单的例子: public class Test { public static void main(String[] args) { try{ Runtime runtime = Runtime.getRuntime();

我使用runtime.exec从Java应用程序中启动另一个应用程序。该子程序在调用system.exit(0)时启动没有问题;从父应用程序开始,父JVM将一直运行,直到子程序终止

下面是一个简单的例子:

    public class Test {

    public static void main(String[] args) {

        try{
             Runtime runtime = Runtime.getRuntime();
             Process p=runtime.exec("cmd /c \"client.exe\"");
             Thread.sleep(10000);
             System.exit(0);
        }
        catch(Exception e){}
    }
}
我希望子应用程序在调用System.exit后继续运行,并使测试应用程序JVM完全关闭

在eclipse中,我得到以下行为:

测试应用程序启动后,client.exe立即启动。在10秒钟的睡眠后,应用程序退出,但从eclipse控制台测试应用程序仍在运行。更奇怪的是,在这一点上点击红色终止按钮没有任何作用。然而,一旦client.exe关闭,父测试应用程序最终终止


然而,更奇怪的是,如果我在eclipse控制台中的红色终止按钮在10秒睡眠结束之前按下,那么测试应用程序将关闭,client.exe将继续运行。这是我想要的行为,但我不明白。有什么想法吗?

这是大多数操作系统的默认行为,在所有子进程终止之前,父进程不能终止

现在,有一种“时髦”的方法来创建一个“无父”进程,这样父进程可以终止,子进程将继续运行,但这取决于操作系统,您已经有了任何方法

基本上,命令行变成了

cmd /C start /B /NORMAL cmd /c "client.exe"
现在。我建议您使用
Runtime 35; exec(String[])
变量,因为这样可以更好地处理命令中的空格

String[] cmd = {"cmd", "/C", "start", "/B", "/NORMAL", "cmd", "/c", "client.exe"};
runtime.exec(cmd);

通常,我会推荐
ProcessBuilder
而不是
Runtime#exec
,因为它允许您更改进程的工作目录……

非常感谢您的回答。我用您建议的(runtime#exec(String[])替换了runtime.exec当client.exe仍然启动时,JVM保持打开状态时,我得到了相同的行为。当然,您已经为我提供了启动的位置。再次感谢!真的,因为我们使用此解决方案作为更新过程的一部分,并且它工作得非常好。我用explorer.exe替换client.exe,它工作得很好。我认为这可能与我的路径和实际文件(client.exe)在文件名中有一个空格的事实。再次感谢您的回答。哦,刚刚记住…这个过程不喜欢长文件名或路径!它与
cmd
有关。我最后不得不使用少量JNI将路径和文件名转换为8.3格式,请注意。。。