2012-08-04 15 views
5

Cuando desarrollé por primera vez un servicio de Java para Windows utilizando apache daemon, utilicé el modo JVM que me gustó mucho. Usted especifica su clase y métodos start \ stop (estáticos). Pero con Linux, Jsvc no parece tener la misma opción. Me gustaría saber por qué?¿Es posible llamar al método dentro de una aplicación Java desde una JVM diferente?

De todos modos si voy a utilizar el sistema init de Linux, estoy tratando de encontrar una manera similar de lograr el mismo comportamiento que es iniciar la aplicación de todos modos, pero para detenerlo, tendré que llamar a un método en una clase.

Mi pregunta es, después de que se haya iniciado el jar, cómo puedo usar las bibliotecas jvm o cualquier otra cosa, llamar un método en mi aplicación (que intentará detener mi aplicación gracefully).

Otra cuestión lado, si se inicia una aplicación y que la aplicación tiene métodos estáticos, Si uso la línea java comando para ejecutar un método main en uno si esa es la clase de aplicación, y el método main, que es static llamarían otra método estático en la clase en la que me gustaría señalar la señal de terminación, ¿llamaría eso en el mismo JVM?

Respuesta

8

¿Por qué no agregar un ShutdownHook a su aplicación?

Un gancho de desconexión es simplemente un hilo inicializado pero no arrancado. Cuando la máquina virtual comienza su secuencia de apagado, iniciará todos los ganchos de cierre registrados en algún orden no especificado y les permitirá ejecutar 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á. Tenga en cuenta que los hilos daemon se continuarán ejecutando durante la secuencia de cierre, al igual que los hilos no daemon si se inició el apagado invocando el método de salida.

Esto permitirá a su frasco termina correctamente antes de ser apagado:

public class ShutdownHookDemo { 
    public void start() { 
     System.out.println("Demo"); 
     ShutdownHook shutdownHook = new ShutdownHook(); 
     Runtime.getRuntime().addShutdownHook(shutdownHook); 
    } 

    public static void main(String[] args) { 
     ShutdownHookDemo demo = new ShutdownHookDemo(); 
     demo.start(); 
     try { 
      System.in.read(); 
     } 
     catch(Exception e) { 
     } 
    } 
} 

class ShutdownHook extends Thread { 
    public void run() { 
     System.out.println("Shutting down"); 
     //terminate all other stuff for the application before it exits 
    } 

} 

Es importante tener en cuenta

Las carreras de gancho de cierre cuando:

  • Un programa existe normalmente Por ejemplo, se llama a System.exit() o sale el último hilo no daemon.
  • finaliza la máquina virtual. p.ej. CTRL-C. Esto corresponde a kill -SIGTERM pid o
  • kill -15 pid en sistemas Unix.

El gancho de cierre no se ejecutará cuando:

  • La máquina virtual aborta
  • Una señal SIGKILL se envía al proceso de la máquina virtual en sistemas Unix. p.ej. kill -SIGKILL pid o kill -9 pid
  • Una llamada TerminateProcess se envía al proceso en sistemas Windows.

Alternativamente, si hay que se puede usar esto para llamar a un método en una clase:

public class ReflectionDemo { 

    public void print(String str, int value) { 
    System.out.println(str); 
    System.out.println(value); 
    } 

    public static int getNumber() { return 42; } 

    public static void main(String[] args) throws Exception { 
    Class<?> clazz = ReflectionDemo.class;//class name goes here 
    // static call 
    Method getNumber = clazz.getMethod("getNumber"); 
    int i = (Integer) getNumber.invoke(null /* static */); 
    // instance call 
    Constructor<?> ctor = clazz.getConstructor(); 
    Object instance = ctor.newInstance(); 
    Method print = clazz.getMethod("print", String.class, Integer.TYPE); 
    print.invoke(instance, "Hello, World!", i); 
    } 
} 

y cargar una clase dinámica:

ClassLoader loader = URLClassLoader.newInstance(
    new URL[] { yourURL }, 
    getClass().getClassLoader() 
); 
Class<?> clazz = Class.forName("mypackage.MyClass", true, loader); 
Class<? extends Runnable> runClass = clazz.asSubclass(Runnable.class); 

Referencias:

Cuestiones relacionadas