如果在java中创建的进程创建子进程,但之后返回,则JVM挂起,但没有进程ID。下面当子进程仍然打开时,为什么Java进程从Gradle挂起?
示例应用程序(需要Windows和Java 7)
import java.io.File;
import java.io.IOException;
import java.lang.ProcessBuilder.Redirect;
import java.nio.file.Files;
public class SubProcessHang {
public static void main(String[] args) throws IOException, InterruptedException {
ProcessBuilder builder = new ProcessBuilder("cmd", "/c", "start", "notepad.exe");
File output = Files.createTempFile("output", "txt").toFile();
builder.redirectError(Redirect.to(output));
builder.redirectOutput(Redirect.to(output));
Process process = builder.start();
process.waitFor();
int exitValue = process.exitValue();
System.out.println("Process exit value:: " + exitValue);
System.out.println("Output file length:: " + output.length());
System.exit(exitValue);
}
}
当应用程序运行时,它会创建三个过程: 爪哇 - > CMD - >记事本 CMD立即返回,Java调用系统。退出(0),这会杀死java进程。 但是记事本仍然存在,并且在从gradle(或者eclipse)运行时,JVM挂起,直到该进程消失,而不是返回它的返回值。
因此,孩子的过程仍然活着,但父母的过程已被部分杀害,但现在被永远搁浅。
的脚本的build.gradle重现此
apply plugin: 'java'
apply plugin: 'application'
mainClassName = "SubProcessHang"
执行“gradle这个运行”,并得到如下的输出:
C:\HangDemo>gradlew run
:compileJava
:processResources UP-TO-DATE
:classes
:run
Process exit value:: 0
Output file length:: 0
> Building 75% > :run
我知道你肯定有事情做与Java进程如何创建,但我不知道该怎么做。
我能做些什么来获取正在运行的java进程的ID并在关闭钩子中查杀所有子进程?
这看起来不像是对我的Gradle真的有用。你有没有尝试过从命令行运行你的课程? –
是的。它按预期工作(正如我所料,无论如何)都是从命令行运行的。它返回退出状态,记事本仍在运行。问题在于gradle是运行这里建模的java进程的自动化工具,并且永远不会返回。 – w25r