Pregunta

Tengo una aplicación Java que inicia otra aplicación Java.El iniciador tiene un temporizador de vigilancia y recibe notificaciones periódicas de la segunda VM.Sin embargo, si no se reciben notificaciones, entonces se debe cerrar la segunda máquina virtual y el iniciador realizará algunas actividades de limpieza adicionales.

La pregunta es, ¿hay alguna manera de hacer esto usando sólo Java?Hasta ahora tengo que usar algunos métodos nativos para realizar esta operación y de alguna manera es feo.

¡Gracias!

¿Fue útil?

Solución

Puede que me esté perdiendo algo, pero ¿no puedes llamar al destroy() método en el Process objeto devuelto por Runtime.exec()?

Otros consejos

Puedes usar java.lang.Proceso para hacer lo que quieras.Una vez que haya creado el proceso anidado y tenga una referencia a la instancia del proceso, puede obtener referencias a sus flujos estándar de salida y error.Puede monitorearlos periódicamente y llamar a .destroy() si desea cerrar el proceso.Todo podría verse así:

Process nestedProcess = new ProcessBuilder("java mysubprocess").start();
InputStream nestedStdOut = nestedProcess.getInputStream(); //kinda backwards, I know
InputStream nestedStdErr = nestedProcess.getErrorStream();
while (true) {
    /*
       TODO: read from the std out or std err (or get notifications some other way)
       Then put the real "kill-me" logic here instead of if (false)
    */
    if (false) {
        nestedProcess.destroy();
        //perform post-destruction cleanup here
        return;
    }

    Thread.currentThread().sleep(1000L); //wait for a bit
}

Espero que esto ayude,

sean

También puede publicar un servicio (a través de arpillera, arpillera, etc.) en la segunda JVM que llama a System.exit() y consumirlo desde la JVM de vigilancia.Si solo desea apagar la segunda JVM cuando deja de enviar esas notificaciones periódicas, es posible que no esté en condiciones de responder a la llamada de servicio.

Llamar comandos de shell con java.lang.Runtime.exec() es probablemente su mejor opción.

La forma habitual de hacer esto es llamar a Process.destroy()...sin embargo, es una solución incompleta ya que cuando se utiliza Sun JVM en *nix, se destruyen mapas en un SIGTERM, lo que no garantiza que finalice el proceso (para eso también necesita SIGKILL).El resultado neto es que no se puede realizar una gestión de procesos real utilizando Java.

Hay algunos errores abiertos sobre este problema, consulte:Texto del enlace

java.lang.Process tiene un método waitFor() para esperar a que muera un proceso y un método destroy() para finalizar el subproceso.

Bien, el giro de la esencia es el siguiente:

Estaba usando Process API para cerrar la segunda máquina virtual, pero no funcionó.

La razón es que mi segunda aplicación es una aplicación Eclipse RCP y la inicié usando el iniciador eclipse.exe incluido.

Sin embargo, eso significa que el método destroy() de Process API se dirigirá al proceso eclipse.exe.Matar este proceso deja ileso al proceso Java.Entonces, uno de mis colegas aquí escribió una pequeña aplicación que eliminará la aplicación correcta.

Entonces, una de las soluciones para usar Process API (y eliminar los pasos intermedios redundantes) es usar el iniciador de Eclipse y hacer que mi primera máquina virtual duplique todas sus funciones.

Supongo que tendré que ponerme a trabajar.

Debería poder hacer los comandos java.lang.Runtime.exec y Shell.

Puede hacer que el código Java detecte la plataforma en tiempo de ejecución y active el comando de proceso de eliminación de la plataforma.Esto es realmente un refinamiento de su solución actual.

También hay Proceso.destruir(), si estás usando el Generador de procesos API

No es exactamente gestión de procesos, pero podría iniciar un servidor rmi en la máquina virtual Java que está iniciando y vincular un remoto instancia con un método que realiza cualquier limpieza necesaria y llama a System.exit().La primera máquina virtual podría entonces llamar a ese método remoto para apagar la segunda máquina virtual.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top