2009-06-22 10 views
19

Me interesan los diferentes enfoques para cerrar con gracia un programa de línea de comandos de Java. Enviar una señal de muerte no es una opción.Mejor manera de cerrar elegantemente un programa de línea de comandos de Java

Puedo pensar en algunos enfoques diferentes.

  1. Abra un puerto y espere la conexión. Cuando uno está hecho, se cierra con gracia.
  2. Mire para que se cree un archivo, luego cierre.
  3. Lea alguna entrada desde el terminal, como "ejecutar apagado".

El tercero no es ideal, ya que a menudo hay una salida de programa bombeada a la pantalla. El primero requiere demasiado esfuerzo (soy flojo). ¿La mayoría de los programadores usan la segunda opción? Si no, ¿qué más es posible/elegante/simple?

+0

¿Quiere decir que un proceso para matar a su programa de línea de comandos java? – Tom

+2

¿Por qué el envío de la señal de matar no es una opción? Como se menciona en las respuestas a continuación, puede atrapar y manejar la señal de muerte con gracia con los ganchos de apagado. – toluju

Respuesta

2

Las dos primeras opciones son fáciles de implementar. También puedes usar algunas cosas JMX (no sé mucho sobre eso). Tomcat usa el primer enfoque y apliqué 1 y 2 en dos de mis proyectos.

9

puede intentar usar Runtime.getRuntime().addShutdownHook() que satisfaga sus requisitos. De esta forma, puede registrar un gancho para realizar limpiezas, a fin de realizar un apagado completo.

EDITAR

http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Runtime.html#addShutdownHook(java.lang.Thread) public void addShutdownHook (gancho del hilo) Registra un nuevo gancho de parada de máquina virtual. La máquina virtual Java se cierra en respuesta a dos tipos de eventos:

  • El programa sale normalmente, cuando las últimas salidas de rosca no daemon o cuando la salida (equivalentemente, System.exit) se invoca el método, o
  • La máquina virtual finaliza en respuesta a una interrupción del usuario, como escribir^C, o un evento en todo el sistema, como cierre de sesión del usuario o cierre del sistema.
+0

Eso no funciona cuando se ejecuta cntrl + c. –

+0

Pero mike, es la forma de degradar con gracia, si se presiona un ctrl + c, cualquier programa cmd terminará con una señal de muerte. –

+0

Ninguna de las otras opciones que mencionó tampoco lo haría, por lo que el comportamiento en ctrl + c probablemente no sea relevante para decidir sobre uno de estos métodos. – Herms

16

puede intentar algo como esto:

Runtime.getRuntime().addShutdownHook(new Thread() { 
    public void run() { /* 
     my shutdown code here 
    */ } 
}); 

edición:

el gancho de cierre no va a realizar el cierre de la aplicación. en su lugar, le da al desarrollador una forma de realizar cualquier limpieza que desee en el momento del cierre.

del Javadoc para Runtime (una buena lectura si usted está planeando utilizar este método):

Un gancho de cierre es simplemente un hilo inicializado pero sin empezar. Cuando la máquina virtual comienza su secuencia de apagado, iniciará todos los enganches de apagado registrados en algún orden no especificado y los dejará funcionar al mismo tiempo. Cuando todos los enganches hayan finalizado, se ejecutarán todos los finalizadores no invocados si se ha habilitado la finalización a la salida. Finalmente, la máquina virtual se detendrá. ...

+0

¿Cómo cierra eso su programa? –

+0

editado. Espero que responda tu pregunta. – akf

+0

¿No debería el método de ejecución tener una anotación @Override? –

5

El beneficio de la segunda opción (verificar un archivo) sobre la primera, escuchar en un puerto, es que tiene alguna posibilidad de seguridad.

Puede establecer los permisos en el directorio donde se crea el archivo para que solo los usuarios apropiados puedan cerrar el programa. Si escucha en un puerto, cualquier usuario puede conectarse a él.

+0

Puede limitar las llamadas entrantes en función de la dirección IP del cliente. Por ejemplo, permite conexiones solo desde localhost. Solo sale cuando es la dirección IP correcta; de lo contrario, cierre la conexión y continúe escuchando una nueva. – akarnokd

+0

@ kd304 - La limitación de las direcciones IP aún permite que cualquier usuario en el sistema local cierre el proceso. Al establecer permisos en el directorio, solo puede permitir un control de usuario específico del proceso. –

0

Yo sugeriría utilizar el gancho de apagado. Permitirá que su programa sea controlado utilizando las herramientas estándar del sistema operativo. Tampoco necesita ningún acceso adicional a recursos externos (disco, puertos, lo que sea).

2

Si quería ir con la versión de socket, es muy simple de implementar. Aquí está el código:

ServerSocket server = new ServerSocket(8080); 
System.out.println("Socket listening!"); 
server.accept(); 
System.out.println("Connection received!"); 

Desde aquí se puede insertar este código en un hilo separado que comenzar con su programa, y ​​luego tener que modificar el estado global para iniciar el apagado.

1

Considere tener un componente JMX. Luego puede conectar con JConsole ya sea localmente o por la red, y comunicarse con su componente. Entonces el componente puede cerrar el programa correctamente.

Con Java 6 u 10, puede hacer lo mismo con JVisualVM.

Cuestiones relacionadas