6

初めて Apache デーモンを使用して Windows 用の Java サービスを開発したとき、私JVMは非常に気に入ったモードを使用しました。クラスと start\stop (静的) メソッドを指定します。しかし、Linux では、Jsvc に同じオプションがあるようには見えません。その理由を本当に知りたいですか?

とにかく、Linux の init システムを使用する場合は、アプリを開始するのと同じ動作を実現する同様の方法を見つけようとしていますが、アプリを停止するには、クラスでメソッドを呼び出す必要があります。 .

私の質問は、jar が開始された後、JVM ライブラリなどを使用してアプリケーション内のメソッドを呼び出す方法です (アプリケーションを正常に停止しようとします)。

アプリケーションが開始され、そのアプリケーションに静的メソッドがある場合、別の副次的な質問です。javaコマンドラインを使用してmainメソッドを実行すると、それがアプリケーションクラスであり、そのmainメソッドstaticは、クラス内の別の静的メソッドを呼び出します。終了シグナルを送信したいのですが、同じ JVM で呼び出しますか?

4

2 に答える 2

8

ShutdownHookアプリケーションに を追加してみませんか?

シャットダウン フックは、単に初期化されているが開始されていないスレッドです。仮想マシンがシャットダウン シーケンスを開始すると、登録されているすべてのシャットダウン フックが不特定の順序で開始され、同時に実行されます。finalization-on-exit が有効になっている場合、すべてのフックが終了すると、呼び出されていないすべてのファイナライザーが実行されます。最後に、仮想マシンが停止します。exit メソッドの呼び出しによってシャットダウンが開始された場合、非デーモン スレッドと同様に、デーモン スレッドはシャットダウン シーケンス中も実行し続けることに注意してください。

これにより、シャットダウンする前に jar を正常に終了できます。

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
    }

}

注意することが重要です

シャットダウン フックは、次の場合に実行されます。

  • プログラムは正常に存在します。たとえば、System.exit() が呼び出されるか、最後の非デーモン スレッドが終了します。
  • 仮想マシンが終了します。たとえば、CTRL-C。これは kill -SIGTERM pid または
  • Unix システムでは kill -15 pid。

次の場合、シャットダウン フックは実行されません。

  • 仮想マシンが中止される
  • SIGKILL シグナルは、Unix システムの仮想マシン プロセスに送信されます。例 kill -SIGKILL pid または kill -9 pid
  • TerminateProcess 呼び出しが Windows システムのプロセスに送信されます。

または、必要に応じて、これを使用してクラスのメソッドを呼び出すことができます。

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

クラスを動的にロードするには:

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

参考文献:

于 2012-08-04T17:57:30.717 に答える
2

基本的に、JVM 間で呼び出す唯一の方法はSockets、直接またはそれに基づく実装を介して を使用することです。RMI

詳細については、http://www.javaworld.com/javaqa/2000-03/03-qa-0324-ipc.htmlを参照してください。

于 2012-08-04T20:58:39.203 に答える