是否可以从不同的JVM中调用java应用程序中的方法?
当我第一次使用apache守护进程为windows开发java服务时,我使用了我喜欢的JVM
模式。 您指定您的类并启动\ stop(静态)方法。 但是对于Linux,Jsvc看起来并没有相同的选择。 我真的很想知道为什么?!
无论如何如果我要使用Linux的init系统,我试图找到一种类似的方法来完成相同的行为,无论如何要启动应用程序但是要停止它,我将不得不在类中调用一个方法。
我的问题是,在jar启动之后,我如何使用jvm库或其他任何东西来调用我的应用程序中的方法(它将尝试优雅地停止我的应用程序)。
另一个问题是,如果应用程序已启动并且该应用程序具有静态方法,那么如果我使用java
命令行在一个应用程序类中运行main
方法,并且main
方法(静态方法)将调用另一个静态方法我希望在终止信号中发出信号的类,是否会在同一个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或
- 在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); } }
并动态加载一个类:
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);
参考文献:
- http://onjava.com/onjava/2003/03/26/shutdownhook.html
- http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Runtime.html#addShutdownHook(java.lang.Thread)
- 如何从C#one正确关闭java应用程序
- 如何在运行时从外部jar访问方法?
- 如何在运行时加载jar文件
基本上,在JVM之间调用的唯一方法是直接使用Sockets
,或者通过基于它的实现,例如RMI
您可能会骗取http://www.javaworld.com/javaqa/2000-03/03-qa-0324-ipc.html以获取更多信息