我有一个需要生成另一个Java应用程序的Java应用程序。第二个java应用程序是长寿的,可能比原始的Java应用程序寿命更长。它基本上是一个执行某些网络代码的大循环,并且除非发生特定情况,否则不打算终止。要启动此应用程序,我使用bash脚本对其进行双重分叉,以便原始java应用程序不会等待它完成:
原始java应用程序如何启动shell脚本:
ProcessBuilder processBuilder = new ProcessBuilder(
"myshellscript",
"-a", "somearg",
"-b", "anotherarg");
final Process process = processBuilder.start();
process.waitFor();
if (process.exitValue() != 0)
{
// do something
}
shell脚本的内容:
fork() {
echo "Going to fork" >> /tmp/output.log
(setsid java -jar ./anotherapplication.jar "$@" &);
echo "Exited" >> /tmp/output.log
}
fork "$@"
在“output.log”中,我看到“Going to fork”和“Exited”消息,但我从未看到来自“anotherapplication.jar”应用程序的任何日志,这让我觉得它没有成功启动。它也没有在ps aux
的输出中显示,所以它肯定没有运行。这是启动第二个应用程序的正确方法,还是我没有正确启动它?
答案 0 :(得分:0)
Setsid应该做你想要的。我不知道为什么你的应用程序没有启动,但是应用程序不会向/tmp/output.log打印任何内容,只是因为你没有将setsid行的输出重定向到日志文件。我会使用:
将该行的stdout和stderr重定向到output.log(setsid java -jar ./anotherapplication.jar "$@" &) >>/tmp/output.log 2&>1
这几乎肯定会显示一个错误,记录它无法启动的原因。无论如何,重置像守护进程这样的进程的标准输入和输出通常是一个好主意。