编辑:看来我的测试,以确定是否原来的JVM已退出有缺陷开始(见接受的答案评论)。对不起,噪音。使用Java,我可以让一个JVM产生另一个JVM,然后让原始的一个退出?
我有一个需要有一个运行的JVM启动另外一个JVM,然后退出。我目前正试图通过Runtime.getRuntime().exec()
来做到这一点。另一个JVM启动,但我的原始JVM不会退出,直到“子”JVM进程停止。看起来使用Runtime.getRuntime().exec()
会在进程之间创建父子关系。是否有某种方式去分离产生的进程,以便父进程可以死亡或者其他一些机制产生进程,而与创建进程没有任何关系?
请注意,这看起来和这个问题完全相同:Using Java to spawn a process and keep it running after parent quits但那里接受的答案实际上并没有工作,至少在我的系统(Windows 7,Java 5和6)上没有。看起来也许这是一个依赖于平台的行为。我正在寻找一个平台独立方式来可靠地调用其他进程,让我原来的进程死亡。
例如,假设我在C:\myjar.jar
有一个jar文件,并且我想运行生活在该jar中的类com.example.RunMe
。比方说,类弹出一个JOptionPane,然后一旦用户点击确定就退出。
现在,以下是在JVM#1运行程序:
public static void main(String[] args) {
String javaHome = System.getProperty("java.home");
String os = System.getProperty("os.name");
String javawBin = javaHome + File.separator + "bin" + File.separator + "javaw";
if (os.toLowerCase().contains("win")) {
javawBin += ".exe";
}
List<String> cmd = new ArrayList<String>();
cmd.add("\"" + javawBin + "\"");
cmd.add("-cp");
cmd.add("\"C:\\myjar.jar\"");
cmd.add("com.example.RunMe");
System.out.println("Running: " + cmd);
try {
System.out.println("Launching...");
Process p = Runtime.getRuntime().exec(cmd.toArray(new String[cmd.size()]));
new Thread(new StreamGobbler(p.getInputStream())).start();
new Thread(new StreamGobbler(p.getErrorStream())).start();
System.out.println("Launched JVM.");
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
}
}
private static class StreamGobbler implements Runnable {
InputStream stream;
StreamGobbler(InputStream stream) {
this.stream = stream;
}
public void run() {
byte[] buf = new byte[64];
try {
while (stream.read(buf) != -1)
;
} catch (IOException e) {
}
}
}
所观察到的现象是,无论 “启动...” 和 “推出JVM。”但JVM#1仅在JVM#2启动的JOptionPane中点击OK后才会退出。另外 - 无论您是否启动流式防护线程,行为都是相同的。
此外,为了救一个人的呼吸,是的,我知道我可以创建一个使用该jar文件构造一个新URLClassLoader和运行这样的说法,但那不是我想要在这里做。
您能否提供样品? – OscarRyz 2010-06-09 20:28:39