这真的是从Java代码启动第二个JVM的最好方法吗?

这是我自己以前的问题的一个后续,我有点不好意思问这个…但无论如何:你将如何从一个独立的Java程序以独立于系统的方式启动第二个JVM? 而且不需要依赖像JAVA_HOME这样的envvariables,因为这可能会指向与当前运行的JRE不同的JRE。 我想出了下面的代码实际上工作,但感觉有点尴尬:

public static void startSecondJVM() throws Exception { String separator = System.getProperty("file.separator"); String classpath = System.getProperty("java.class.path"); String path = System.getProperty("java.home") + separator + "bin" + separator + "java"; ProcessBuilder processBuilder = new ProcessBuilder(path, "-cp", classpath, AnotherClassWithMainMethod.class.getName()); Process process = processBuilder.start(); process.waitFor(); } 

而且,当前正在运行的JVM可能已经被第二个JVM不知道的其他参数(-D,-X …,…)启动了。

对于我来说,在启动一个辅助进程的时候,你总是希望使用完全相同的参数,类path或者其他任何东西(特别是-X种东西 – 例如,为什么孩子需要和父节点相同的堆设置)。

我宁愿使用某种外部configuration来为孩子定义这些属性。 这是一个更多的工作,但我认为最终你需要灵活性。

要查看可能的configuration设置的范围,您可以查看Eclipse中的“运行configuration”设置。 不less值得一提的configuration。

我认为答案是“是”。 这可能与使用独立于系统的代码在Java中所做的一样好。 但请注意,即使这只是相对独立的系统。 例如,在一些系统中:

  1. JAVA_HOMEvariables可能没有被设置,
  2. 用于启动JVM的命令名称可能不同(例如,如果它不是Sun JVM),或者
  3. 命令行选项可能不同(例如,如果它不是Sun JVM)。

如果我打算在启动(第二个)JVM时实现最大的可移植性,我想我会使用包装脚本来做到这一点。

要find你的代码当前正在运行的java可执行文件(即你的问题示例代码中的'path'variables),在apache ant中有一个实用的方法可以帮助你。 你不必用antbuild立你的代码 – 只要把它作为一个库,就可以用这个方法。

它是:

org.apache.tools.ant.util.JavaEnvUtils.getJreExecutable( “Java” 的)

它负责处理其他人提到的不同JVM供应商的特殊情况。 (并且看它的源代码,有比我想象的更多的特殊情况。)

它在ant.jar中。 ant是分布在Apache的许可证,所以希望你可以使用它,你怎么想没有麻烦。