简体   繁体   English

是否可以从不同的 JVM 调用 Java 应用程序中的方法?

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

When I first developed a Java service for Windows using Apache daemon, I used the JVM mode which I liked a lot.当我第一次使用 Apache 守护进程为 Windows 开发 Java 服务时,我使用了我非常喜欢的JVM模式。 You specify your class and start\stop (static) methods.您指定您的类和开始\停止(静态)方法。 But with Linux, Jsvc doesn't look like it has the same option.但是对于 Linux,Jsvc 看起来没有相同的选项。 I would really like to know why?!我真的很想知道为什么?!

Anyway If I'm going to use Linux's init system, I'm trying to find a similar way to accomplish the same behavior which is to start the app in anyway but to stop it, I'll have to call a method in a class.无论如何,如果我要使用 Linux 的 init 系统,我会尝试找到一种类似的方法来完成相同的行为,即以任何方式启动应用程序但要停止它,我将不得不调用类中的方法.

My question is, after the jar is started, how can I use the JVM libraries or anything else, to call a method in my application (which will attempt to stop my application gracefully ).我的问题是,在 jar 启动后,我如何使用 JVM 库或其他任何东西来调用我的应用程序中的方法(这将尝试正常停止我的应用程序)。

Another side question, if an application is started and that application has static methods, If I use the java command line to run a main method in one if that's application class, and the main method, which is static would call another static method in the class in which I would like to signal the termination signal, would that call by in the same JVM?另一个问题,如果启动了一个应用程序并且该应用程序具有静态方法,如果我使用java命令行在一个应用程序类中运行一个main方法,而staticmain方法将调用另一个静态方法我想在其中发出终止信号的类,该调用会在同一个 JVM 中调用吗?

Why not rather add a ShutdownHook to your application?为什么不向您的应用程序添加一个ShutdownHook

A shutdown hook is simply an initialized but unstarted thread.关闭挂钩只是一个已初始化但未启动的线程。 When the virtual machine begins its shutdown sequence it will start all registered shutdown hooks in some unspecified order and let them run concurrently.当虚拟机开始其关闭序列时,它将以某种未指定的顺序启动所有已注册的关闭挂钩,并让它们同时运行。 When all the hooks have finished it will then run all uninvoked finalizers if finalization-on-exit has been enabled.当所有挂钩完成后,如果启用了退出时终结,它将运行所有未调用的终结器。 Finally, the virtual machine will halt.最后,虚拟机将停止。 Note that daemon threads will continue to run during the shutdown sequence, as will non-daemon threads if shutdown was initiated by invoking the exit method.请注意,守护线程将在关闭序列期间继续运行,如果关闭是通过调用 exit 方法启动的,非守护线程也将继续运行。

This will allow your jar to terminate gracefully before being shutdown:这将允许您的 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
    }

}

It is important to note重要的是要注意

The shutdown hook runs when:关闭挂钩在以下情况下运行:

  • A program exists normally.程序正常存在。 For example, System.exit() is called, or the last non-daemon thread exits.例如,System.exit() 被调用,或者最后一个非守护线程退出。
  • the Virtual Machine is terminated.虚拟机被终止。 eg CTRL-C.例如 CTRL-C。 This corresponds to kill -SIGTERM pid or这对应于 kill -SIGTERM pid 或
  • kill -15 pid on Unix systems. kill -15 pid 在 Unix 系统上。

The shutdown hook will not run when:关闭挂钩在以下情况下不会运行:

  • The Virtual Machine aborts虚拟机中止
  • A SIGKILL signal is sent to the Virtual Machine process on Unix systems. SIGKILL 信号被发送到 Unix 系统上的虚拟机进程。 eg kill -SIGKILL pid or kill -9 pid例如 kill -SIGKILL pid 或 kill -9 pid
  • A TerminateProcess call is sent to the process on Windows systems.将 TerminateProcess 调用发送到 Windows 系统上的进程。

Alternatively if you must you can use this to call a method in a class:或者,如果必须,您可以使用它来调用类中的方法:

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

and to load a class dynamically:并动态加载一个类:

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

References:参考:

Basically the only way to call between JVMs is through the use of Sockets , either directly or via implementations based on it, such as RMI基本上,在 JVM 之间调用的唯一方法是直接使用Sockets或通过基于它的实现,例如RMI

You might lie to check out http://www.javaworld.com/javaqa/2000-03/03-qa-0324-ipc.html for further info您可能会撒谎查看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