Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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. You specify your class and start\stop (static) methods. But with Linux, Jsvc doesn't look like it has the same option. 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.

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

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?

like image 918
Muhammad Gelbana Avatar asked Aug 04 '12 17:08

Muhammad Gelbana


2 Answers

Why not rather add a ShutdownHook to your application?

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.

This will allow your jar to terminate gracefully before being shutdown:

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.
  • the Virtual Machine is terminated. e.g. CTRL-C. This corresponds to kill -SIGTERM pid or
  • kill -15 pid on Unix systems.

The shutdown hook will not run when:

  • The Virtual Machine aborts
  • A SIGKILL signal is sent to the Virtual Machine process on Unix systems. e.g. kill -SIGKILL pid or kill -9 pid
  • A TerminateProcess call is sent to the process on Windows systems.

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:

  • 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)
  • How to shutdown java application correctly from C# one
  • How does one access a method from an external jar at runtime?
  • How to load a jar file at runtime
like image 86
David Kroukamp Avatar answered Nov 09 '22 06:11

David Kroukamp


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

You might lie to check out http://www.javaworld.com/javaqa/2000-03/03-qa-0324-ipc.html for further info

like image 20
MadProgrammer Avatar answered Nov 09 '22 05:11

MadProgrammer