2012-01-04 7 views
6

Tengo tres clases que dicen alfa, beta, gamma y cada una de las tres clases tiene un método main.Cómo ejecutar código después de una llamada a Sytem.exit (0) en un bloque finally

Tanto alfa y clases beta han, dentro de su método main, un bloque try...catch...finally como:

public class alpha{ 

    public static void main(String[] args){ 
     try{ 
      Do something; 
     }catch(Exception ex){ 
      ex.printStackTrace(); 
     } 
     finally{ 
      System.exit(0); 
     } 
    } 
} 


public class beta{ 

    public static void main(String[] args){ 
     try{ 
      Do something; 
     }catch(Exception ex){ 
      ex.printStackTrace(); 
     } 
     finally{ 
      System.exit(0); 
     } 
    } 
} 

Ahora en la clase gamma i llaman principales métodos de clases de alfa y beta para funcionar continuamente, como a continuación

public gamma{ 

    public static void main(String[] args) { 
     try { 
      alpha.main(arg); 
      beta.main(arg1); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
} 

El problema es que nunca se llega al código beta.main(arg1) debido al System.exit(0) dentro del bloque finally de la clase alpha. Dado que alfa y beta son aplicaciones independientes cuando se ejecutan por separado, deben finalizar el servicio al final del programa. Así que ahora hay alguna forma de llegar a la línea beta.main(arg1) sin cambiar demasiado la funcionalidad real de las clases alfa y beta.

Por favor, hágamelo saber si necesita más detalles. Gracias de antemano ...

+1

posible duplicado de [Prevención System.exit() de API] (http://stackoverflow.com/questions/5401281/preventing-system -exit-from-api) – Mat

Respuesta

4

En tal caso, el gancho de cierre se puede utilizar:

public class Gamma{ 

    public static void main(String[] args) { 
     try { 
     Thread hook = new Thread() { public void run() { Beta.main(args); } }; 
      hook.setDaemon(true); 
      Runtime.getRuntime().addShutdownHook(hook); 
      Alpha.main(args); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 
+0

Agradable. Nunca pensé en utilizar ganchos de apagado como mecanismo de continuación. –

+0

Gran respuesta ... Muchas gracias Vlad .... :-) – coolgokul

+0

De nada) – Vlad

2

(Idealmente, nada de lo que forma parte de la API pública de un módulo jamás debe hacer nada que llama exit, y el método de una clase main debe ser sólo una pequeña cuña que invoca otra cosa que hace el verdadero trabajo antes de producir el código de salida apropiado.)

dicho esto, si desea evitar que System.exit, se puede registrar un SecurityManager que convierte las llamadas a System.exit en SecurityException s o s Error.

System.exit:

tiros

SecurityException - si existe un administrador de seguridad y su método checkExit no permite la salida con el estado especificado.

Algo así como

System.setSecurityManager(new SecurityManager() { 
    @Override 
    public void checkExit(int exitCode) throws SecurityException { 
    throw new SecurityException("stop that"); 
    } 
}); 

A continuación, el método que está llamando métodos principales solo pueden atrapar y suprimir ese SecurityException. Puede hacerlo más robusto creando su propio ExitCalledError y lanzándolo en su lugar y solo suprimiéndolo.

Me resulta muy útil para evitar que los corredores de pruebas unitarias informen falsamente de éxito cuando el corrector de prueba es exit ed por código bajo prueba con un código de salida cero.

+0

Hm. No puedo decidir lo que pienso sobre esto. Odio usar el SecurityManager para hacer cosas que no son de seguridad, pero este es un tipo de hack elegante. –

+1

@CharlieMartin, estoy de acuerdo en que es un truco. Es bastante robusto a medida que avanzan los ataques, y algunas preocupaciones, la confiabilidad de los comentarios de los corredores de prueba, lo justifican. Por supuesto, hay problemas, la mera presencia de un 'SecurityManager' puede hacer sutiles errores en el código de la biblioteca y puede afectar la forma en que la VM optimiza las cosas. –

+0

Bueno, y lo voté en alza. Todavía no he decidido lo que pienso de él. –

1

Realmente, la única solución es deshacerse de la llamada System.exit(). Esta es la razón por la cual System.exit() es malo. Una buena forma de reemplazarlos es lanzar una excepción: puede agregar un manejador de excepciones al sistema (busque agregarlos a ThreadGroups para agregar uno por cada ruta de excepción) y luego decidir qué desea hacer.

0

System.exit(0) finaliza la máquina virtual Java actualmente en ejecución. Cierra todas las aplicaciones en la VM, no solo la aplicación que llama al System.exit(0).Necesita pensar una alternativa para su funcionalidad. Aquí hay un enlace al respecto. System.exit usage

Cuestiones relacionadas