2012-08-04 4 views
5

Als ich zum ersten Mal einen Java-Dienst für Windows mit Apache-Daemon entwickelte, benutzte ich den JVM-Modus, den ich sehr mochte. Sie geben Ihre Klasse an und starten \ stop (statische) Methoden. Aber unter Linux sieht Jsvc nicht so aus, als hätte es dieselbe Option. Ich würde wirklich gerne wissen warum?Kann eine Methode innerhalb einer Java-Anwendung von einer anderen JVM aufgerufen werden?

Egal, wenn ich Linux Init-System verwenden werde, versuche ich eine ähnliche Möglichkeit zu finden, das gleiche Verhalten zu erreichen, die App in jedem Fall zu starten, aber um es zu stoppen, muss ich eine anrufen Methode in einer Klasse.

Meine Frage ist, nachdem das Glas gestartet wird, wie kann ich die jvm-Bibliotheken oder irgendetwas anderes verwenden, um eine Methode in meiner Anwendung aufzurufen (die versuchen wird, meine Anwendung zu stoppen anmutig).

Ein andere Seite Frage, wenn eine Anwendung gestartet wird, und dass die Anwendung statische Methoden hat, wenn ich die java Kommandozeile eine main Methode in einer wenn das Anwendungsklasse und die main Methode, die static andere nennen würde laufen Statische Methode in der Klasse, in der ich das Terminierungssignal signalisieren möchte, würde das durch JVM anrufen?

Antwort

8

Warum nicht eher eine ShutdownHook zu Ihrer Anwendung hinzufügen?

Ein Shutdown-Hook ist einfach ein initialisierter, aber nicht mit einem Thread versehener Thread. Wenn die virtuelle Maschine ihre Abschaltsequenz beginnt, werden alle registrierten Herunterfahren-Hooks in einer nicht angegebenen Reihenfolge gestartet und gleichzeitig ausgeführt. Wenn alle Hooks abgeschlossen sind, werden alle nicht initialisierten Finalizer ausgeführt, wenn finalization-exit aktiviert wurde. Schließlich wird die virtuelle Maschine angehalten. Beachten Sie, dass die Daemon-Threads während der Shutdown-Sequenz weiterhin ausgeführt werden, ebenso die Nicht-Daemon-Threads , wenn das Herunterfahren durch Aufrufen der Exit-Methode eingeleitet wurde.

Dies ermöglicht Ihr Glas, bevor sie Herunterfahren ordnungsgemäß zu beenden:

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 ist wichtig,

Die Shutdown-Hook läuft zu beachten, wenn:

  • Ein Programm existiert normalerweise. Zum Beispiel wird System.exit() aufgerufen, oder der letzte Nicht-Daemon-Thread wird beendet.
  • die virtuelle Maschine ist beendet. z.B. STRG-C. Dies entspricht kill -SIGTERM pid oder
  • kill -15 pid auf Unix-Systemen.

Die Abschaltung Haken werden nicht ausgeführt, wenn:

  • Die Virtual Machine
  • A SIGKILL Signal an dem Virtual Machine Prozess bricht auf Unix-Systemen gesendet wird. z.B. kill -SIGKILL pid oder kill -9 pid
  • Ein TerminateProcess-Aufruf wird an den Prozess auf Windows-Systemen gesendet.

Alternativ, wenn Sie müssen, können Sie diese verwenden, um eine Methode in einer Klasse zu nennen:

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

und eine Klasse dynamisch zu laden:

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

Referenzen: