【发布时间】:2015-12-14 11:48:59
【问题描述】:
我有一个 java jar 命令,我使用 Popen 从 python 内部调用它。我很高兴我做对了,我这样做的原因有很多(不是很好,但就是这样)。
当我在本地运行 Java 时,它工作正常(JRE 1.8),当我在本地运行调用 Java 的 python 时,它工作正常。当我在 docker 容器中运行它时,它只是挂起 - process.communicate() 上的 python,当我执行 docker exec 时,它只是不返回(命令的输出完全符合我的预期)。
我发现除非在 Java 末尾有一个显式的 System.exit(0);,否则 Java 进程不会在 在 docker 容器内运行时结束 - 它只是挂起,在完成所有处理的点。
为了检查这一点,我制作了一个由 5 行组成的 Hello World 应用程序(我注释掉或输入 System.exit 以检查它是否有效)
public class Hello {
public static void main(String[] args) {
System.out.println("Heellllooo");
// System.exit(0);
}
}
我将它捆绑到一个 Jar 中,并将它放在“真实”jar 所在的文件夹中,然后执行。
没有system.exit(),进程挂起。有了它,它就会干净地退出。在这两种情况下,都会打印“Heellllloooo”。
其他可能有助于诊断我用来检查的命令的随机事实是:(python 中的 popen 与我传递给 Java 的参数相比要复杂得多)。
docker exec [tag] java -jar libs/Hello.jar
如果我这样做:
docker exec [tag] java -version
它会立即返回版本信息。
我正在运行 Mac,所以这是在 docker-machine boot2docker Ubuntu vm 中运行的。在 Debian 和 Ubuntu 机器上运行相同 docker-images 的其他人对此完全没有任何问题。
我不认为问题与 Python 有任何关系,因为从 exec 运行它时会出现症状(因此我没有将它标记为 python)。
我的问题:为什么main函数返回时java进程不退出?
说清楚,我不想知道如何杀死进程(我知道怎么做),我想知道为什么进程不返回。 (这似乎是一个特定的 java / docker 事情)。
【问题讨论】:
-
@a3.14_Infinity 我认为这些问题与我没有使用的 -i 交互有关。如果您使用 -i 并且不关闭输入流,它似乎会挂起(这很有意义,即使它有点令人沮丧) - 我没有触及 system.in。 -t 对我没有任何作用(并且在 popen() 子函数中运行时也无济于事(我认为))。链接 2 是关于僵尸的——这个进程不是僵尸,它只是没有返回。
-
@VonC 这个链接虽然很有趣,但我看不出它是如何关联的:当我运行 docker exec 时,我没有发出 sigterm 或 sigkill 命令。所有其他命令(如 exec ls 或 exec uname -a,甚至 exec java -version)工作正常并返回。你有什么具体的意思吗?
-
@JamesTaylor 以防万一它是一个僵尸进程,但你提到它不是。所以它不适用于你的问题(这就是为什么我只提到它作为评论,而不是答案)
标签: java macos docker boot2docker