簡體   English   中英

是否可以從不同的 JVM 調用 Java 應用程序中的方法?

[英]Is it possible to call method within a Java application from a different JVM?

當我第一次使用 Apache 守護進程為 Windows 開發 Java 服務時,我使用了我非常喜歡的JVM模式。 您指定您的類和開始\停止(靜態)方法。 但是對於 Linux,Jsvc 看起來沒有相同的選項。 我真的很想知道為什么?!

無論如何,如果我要使用 Linux 的 init 系統,我會嘗試找到一種類似的方法來完成相同的行為,即以任何方式啟動應用程序但要停止它,我將不得不調用類中的方法.

我的問題是,在 jar 啟動后,我如何使用 JVM 庫或其他任何東西來調用我的應用程序中的方法(這將嘗試正常停止我的應用程序)。

另一個問題,如果啟動了一個應用程序並且該應用程序具有靜態方法,如果我使用java命令行在一個應用程序類中運行一個main方法,而staticmain方法將調用另一個靜態方法我想在其中發出終止信號的類,該調用會在同一個 JVM 中調用嗎?

為什么不向您的應用程序添加一個ShutdownHook

關閉掛鈎只是一個已初始化但未啟動的線程。 當虛擬機開始其關閉序列時,它將以某種未指定的順序啟動所有已注冊的關閉掛鈎,並讓它們同時運行。 當所有掛鈎完成后,如果啟用了退出時終結,它將運行所有未調用的終結器。 最后,虛擬機將停止。 請注意,守護線程將在關閉序列期間繼續運行,如果關閉是通過調用 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 或
  • kill -15 pid 在 Unix 系統上。

關閉掛鈎在以下情況下不會運行:

  • 虛擬機中止
  • 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);

參考:

基本上,在 JVM 之間調用的唯一方法是直接使用Sockets或通過基於它的實現,例如RMI

您可能會撒謊查看http://www.javaworld.com/javaqa/2000-03/03-qa-0324-ipc.html以獲取更多信息

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM