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

Muh*_*ana 6 java jvm init ubuntu-12.04

当我第一次使用apache守护进程为windows开发java服务时,我使用了JVM我非常喜欢的模式.您指定您的类并启动\ stop(静态)方法.但是对于Linux,Jsvc看起来并没有相同的选择.我真的很想知道为什么?!

无论如何如果我要使用Linux的init系统,我试图找到一种类似的方法来完成相同的行为,无论如何都要启动应用程序,但要停止它,我将不得不在类中调用一个方法.

我的问题是,在启动jar之后,我如何使用jvm库或其他任何东西来调用我的应用程序中的方法(它会尝试优雅地停止我的应用程序).

另一个问题,如果一个应用程序启动并且该应用程序具有静态方法,如果我使用java命令行在一个main方法中运行一个方法,如果那个应用程序类,那么main方法,这static将调用我在类中的另一个静态方法想要发出终止信号的信号,是否可以通过相同的方式呼叫JVM

Dav*_*amp 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
    }

}
Run Code Online (Sandbox Code Playgroud)

重要的是要注意

关闭钩子运行时:

  • 程序通常存在.例如,调用System.exit(),或者退出最后一个非守护程序线程.
  • 虚拟机已终止.例如CTRL-C.这对应于kill -SIGTERM pid或
  • 在Unix系统上杀死-15 pid.

在以下情况下,关闭钩子不会运行:

  • 虚拟机中止
  • SIGKILL信号被发送到Unix系统上的虚拟机进程.例如杀死-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);
  }
}
Run Code Online (Sandbox Code Playgroud)

并动态加载一个类:

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);
Run Code Online (Sandbox Code Playgroud)

参考文献: