studio reales proyectos para libro introducción incluye herramientas fuente español desarrollo código con avanzado aplicaciones java eclipse shutdown

java - reales - Cómo obtener shutdown hook para ejecutar en un proceso iniciado desde Eclipse



libro de android studio en español pdf (7)

No estoy seguro de cómo solucionar esto, pero IntelliJ agregó un botón por separado a su diálogo ''Ejecutar'' que apagará la máquina virtual de una manera que llame a los ganchos de cierre. Su depurador no tiene esta característica.

Tengo un gancho de cierre en mi aplicación (creado usando Runtime.getRuntime().addShutdownHook ). Sin embargo, si ejecuto la aplicación desde Eclipse, cuando se apaga, el gancho de cierre no se ejecuta.

Creo que esto se debe a que Eclipse envía el equivalente de una señal de destrucción de fuerza al proceso, lo que no hace que se ejecute el gancho de desconexión (equivalente a taskkill / F en Windows o kill -p en Linux), aunque yo '' No estoy absolutamente seguro

¿Alguien sabe cómo evitar esto? Estoy ejecutando Windows (Vista) y tengo la sensación de que puede tratarse de un problema específico de Windows, pero no estoy seguro.


En primer lugar, ¿está terminando su aplicación o la está terminando a la fuerza? Si lo finaliza por la fuerza (mediante el botón de detener), este informe de error de Eclipse tiene detalles sobre por qué esto podría no funcionar.

De lo contrario, es posible que tenga razón acerca de que se trata de un comportamiento específico de Windows. Estoy en una Mac así que no puedo confirmar, lo siento. Sin embargo, puedo decirle que el siguiente programa de prueba ejecuta los ganchos de apagado como se esperaba.

public class MyShutdownHook { public static void main( String[] args ) { System.out.println( "Entering main." ); Runtime.getRuntime().addShutdownHook( new Thread( new Runnable() { public void run() { System.out.println( "Shutdown hook ran." ); } } ) ); System.out.println( "Exiting main." ); } }

Los Javadocs para Runtime # addShutdownHook mencionan que los ganchos de cierre no se ejecutan cuando se anula la JVM, no se sale normalmente, así que, de nuevo, es probable que esté en lo correcto en sus suposiciones. Dicho esto, aquí hay algunas cosas que probar. De nuevo, lo siento, no puedo confirmar esto de antemano, no hay Windows aquí. (¡Bendito!)

  • Asegúrese de que la JVM no incluya la opción -Xrs . Esto tiene un efecto secundario en los ganchos de cierre.
  • Intente iniciar JVM utilizando la opción -server o -client . Según mi experiencia, el comportamiento de mayúsculas y minúsculas puede verse afectado por la elección del modo VM. (Especialmente con respecto a enhebrar, al menos en Mac)
  • ¿Estás iniciando tu aplicación en un generador de perfiles o similar? Cargando cualquier biblioteca nativa?
  • ¿Estás recibiendo un error fatal y te lo estás perdiendo? Por ejemplo, OutOfMemoryError o similar?
  • Intente marcar / desmarcar la opción Iniciar en segundo plano del diálogo Ejecutar configuración de su aplicación en Eclipse.
  • Por último, pero no menos importante: invoque System.exit () manualmente si tiene la oportunidad. :)

Estoy atrapado en websphere en este momento, y no veo lo que estoy buscando. Pero sí recuerdo que eclipse tiene una opción de configuración de ejecución relacionada con el inicio de la aplicación en la misma máquina virtual. ¿Es posible que lance su aplicación java en la misma máquina virtual que la máquina virtual eclipse?

Pero la opción se me escapa.


Aquí hay una secuencia de comandos que puede ejecutar fuera de eclipse para enumerar los procesos disponibles que se ejecutan en Eclipse que podría matar.

#!/bin/bash set -o nounset # Treat unset variables as an error PROCESSES=$(ps axo pid,ppid,command) # Find eclipse launcher PID LAUNCHER_PID=$(echo "$PROCESSES" | grep "/usr/lib/eclipse/eclipse" |grep -v "launcher"|awk ''{print $1}'') echo "Launcher PID $LAUNCHER_PID" # Find eclipse PID ECLIPSE_PID=$(echo "$PROCESSES" | egrep "[[:digit:]]* $LAUNCHER_PID " | awk ''{print $1}'') echo "Eclipse PID $ECLIPSE_PID" # Find running eclipse sub-process PIDs SUB_PROCESS=$(echo "$PROCESSES" | egrep "[[:digit:]]* $ECLIPSE_PID " | awk ''{print $1}'') # List processes echo for PROCESS in $SUB_PROCESS; do DRIVER=$(ps --no-headers o pid,ppid,command $PROCESS | awk ''{print $NF}'') echo "$PROCESS $DRIVER" done echo "Kill a process using: ''kill -SIGTERM /$PID''"


Sairam está aquí, llamando a System.exit (0) podemos finalizar eclipse JVM y podemos ver los resultados de Shutdown hook


Usé el siguiente truco al final de mi método principal para resolver el problema:

if (Boolean.parseBoolean(System.getenv("RUNNING_IN_ECLIPSE"))) { System.out.println("You''re using Eclipse; click in this console and " + "press ENTER to call System.exit() and run the shutdown routine."); try { System.in.read(); } catch (IOException e) { e.printStackTrace(); } System.exit(0); }


En Windows para detener correctamente una aplicación Java de forma estándar, debe enviar Ctrl + C. Esto solo funciona con aplicaciones de consola, pero Eclipse usa javaw.exe lugar de java.exe . Para solucionar esto, abra la configuración de inicio, la pestaña JRE y seleccione "JRE alternativo:". Aparece el cuadro de grupo "Ejecutable de Java" y permite ingresar el ejecutable alternativo "java".

Ahora necesitamos un programa externo para enviar Ctrl-C a un proceso con una consola oculta. Encontré consejos aquí y aquí . Nuestro programa se conecta a la consola del proceso deseado y envía el evento de la consola.

#include <stdio.h> #include <windows.h> int main(int argc, char* argv[]) { if (argc == 2) { unsigned pid = 0; if (sscanf_s(argv[1], "%u", &pid) == 1) { FreeConsole(); // AttachConsole will fail if we don''t detach from current console if (AttachConsole(pid)) { //Disable Ctrl-C handling for our program SetConsoleCtrlHandler(NULL, TRUE); GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); return 0; } } } return 1; }

Prueba el programa java:

public class Shuthook { public static void main(final String[] args) throws Exception { Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { System.out.println("Shutting down..."); } }); String sPid = ManagementFactory.getRuntimeMXBean().getName(); sPid = sPid.substring(0, sPid.indexOf(''@'')); System.out.println("pid: " + sPid); System.out.println("Sleeping..."); Thread.sleep(1000000); } }

Terminarlo:

C:/>killsoft.exe 10520

Salida del programa de prueba en Eclipse:

pid: 10520 Sleeping... Shutting down...