2012-08-04 5 views
5

Quando ho sviluppato per la prima volta un servizio java per Windows usando demone apache, ho usato la modalità che mi è piaciuta molto. Si specificano i metodi di classe e start \ stop (statici). Ma con Linux, Jsvc non sembra avere la stessa opzione. Mi piacerebbe davvero sapere perché ?!È possibile chiamare il metodo all'interno di un'applicazione java da una JVM diversa?

In ogni caso Se sto per utilizzare il sistema di init di Linux, sto cercando di trovare un modo simile per realizzare lo stesso comportamento che è quello di avviare l'app in ogni caso, ma per fermarlo, dovrò chiamare un metodo in una classe.

La mia domanda è, dopo l'avvio del vaso, come posso utilizzare le librerie JVM o qualsiasi altra cosa, per chiamare un metodo nella mia applicazione (che tenterà di fermare la mia applicazione grazia).

Un'altra domanda lato, se un'applicazione è avviata e che l'applicazione ha metodi statici, Se uso la linea java comando per eseguire un metodo main in uno se è classe di applicazione, e il metodo main, che è static chiamerebbero un altro metodo statico nella classe in cui vorrei segnalare il segnale di terminazione, chiamerebbe nello stesso JVM?

risposta

8

Perché non aggiungere uno ShutdownHook alla tua applicazione?

Un hook di arresto è semplicemente un thread inizializzato ma non avviato. Quando la macchina virtuale inizia la sua sequenza di spegnimento, avvierà tutti i ganci di arresto registrati in un ordine non specificato e li consentirà di eseguire contemporaneamente . Al termine di tutti i ganci, verranno eseguiti tutti i finalizzatori non inviati se è stata abilitata la finalizzazione all'uscita. Infine, la macchina virtuale si fermerà. Si noti che i thread daemon eseguiranno durante la sequenza di spegnimento, così come i thread non-daemon se l'arresto è stato avviato richiamando il metodo exit.

Questo permetterà al vaso per terminare con grazia prima di spegnimento:

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 
    } 

} 

È importante notare

Le corse gancio arresto quando:

  • Un programma esiste normalmente. Ad esempio, viene chiamato System.exit() o viene chiuso l'ultimo thread non daemon.
  • la Macchina virtuale è terminata. per esempio. CTRL-C. Questo corrisponde a kill -SIGTERM pid o
  • kill -15 pid su sistemi Unix.

Il gancio di arresto non viene eseguito quando:

  • Virtual Machine interrompe
  • Un segnale SIGKILL viene inviato al processo macchina virtuale su sistemi Unix. per esempio. kill -SIGKILL pid o kill -9 pid
  • Una chiamata TerminateProcess viene inviata al processo su sistemi Windows.

In alternativa, se è necessario è possibile utilizzare questo per chiamare un metodo in una classe:

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); 
    } 
} 

e per caricare una classe in modo dinamico:

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); 

Riferimenti: