Editar: Parece que mi prueba para determinar si la JVM original había salido era defectuosa para empezar (ver comentarios en la respuesta aceptada). Perdón por el ruido.Usando Java, ¿puedo hacer que una JVM genere otra, y luego hacer que la original salga?
Necesito tener una JVM en ejecución para iniciar otra JVM y luego salir. Actualmente estoy tratando de hacer esto a través del Runtime.getRuntime().exec()
. La otra JVM se inicia, pero mi JVM original no saldrá hasta que se detenga el proceso de JVM "hijo". Parece que usar Runtime.getRuntime().exec()
crea una relación padre-hijo entre los procesos. ¿Hay alguna forma de desvincular el proceso generado para que el padre pueda morir, o algún otro mecanismo para engendrar un proceso sin ninguna relación con el proceso de creación?
Tenga en cuenta que esto parece exactamente como esta pregunta: Using Java to spawn a process and keep it running after parent quits pero la respuesta aceptada no funciona, al menos no en mi sistema (Windows 7, Java 5 y 6). Parece que tal vez este es un comportamiento dependiente de la plataforma. Estoy buscando una plataforma independiente manera de invocar de manera confiable el otro proceso y dejar que mi proceso original muera.
Por ejemplo, supongamos que tengo un archivo jar en C:\myjar.jar
y quiero ejecutar la clase com.example.RunMe
que vive en ese contenedor. Digamos que la clase muestra un JOptionPane, y luego sale una vez que el usuario ha tocado OK.
Ahora, el siguiente es el programa que se ejecuta en la 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) {
}
}
}
El comportamiento observado es que tanto "El lanzamiento de ..." y "Lanzado JVM." se imprimen, pero JVM n. ° 1 solo sale después de presionar Aceptar en JOptionPane lanzado por JVM n. ° 2. Además, el comportamiento es el mismo ya sea que inicie o no los hilos de los gobblers de la transmisión o no.
Además, para salvar a alguien la respiración, sí sé que podría crear un nuevo URLClassLoader con ese archivo jar y ejecutarlo de esa manera, pero eso no es lo que estoy tratando de hacer aquí.
¿Puede proporcionar una muestra? – OscarRyz