0

I want to restart a java application when it is stopped. This stackoverflow question addresses how to start a java application.

Is it possible to make a program restart itself when it is shutdown? Or save its state before exiting?

My first approach was trying to run a thread passing the following Runnable implementation:

public void run() {
    try {
        while(true) {
            // perform important computations
        }
    }
    catch(Throwable t) {
        // save state before exiting and start again
        System.out.println("saving...");
    }       
}

This did not work, because when I press Ctrl+C the program produces no output, which means that any code with a ProcessBuilder will not run too.

In case it's not possible, how can I keep an application running (either stop it from being shutdown and/or start it again once it's shutdown) using other programming languages or using operating system settings (e.g. UNIX)?


Update: I used pens-fan-69's code along with a ProcessBuilder instance. For reference, here's how the code looks:

public class Unkillable {

  public static void main(String[] args) {
      System.out.println("I'm running!");
      Runtime runtime = Runtime.getRuntime();
      runtime.addShutdownHook(new Thread() {
          @Override
          public void run() {
              // save state before exiting and start again
              System.out.println("Shuting down...");
              ProcessBuilder pb = new ProcessBuilder("java", "Unkillable");
              try {
                  pb.start();
              } catch (IOException e) {
                  System.out.println("Error executing callback function.");
              }
          }
      });

      while(true) {
          // fancy code goes here
      }
  }
}

This comes with a side effect: when you run this on a console, hitting Ctrl+C will make the program invisible, running in the background. I was then able to kill the remaining process via the activity monitor. If this class received input from the user, this would be of little use. I wonder if there's anyway to associate the new process with a console or something similar.

Community
  • 1
  • 1
goncalotomas
  • 960
  • 1
  • 12
  • 27
  • 1
    Did you check this: http://stackoverflow.com/questions/1216172/how-can-i-intercept-ctrlc-in-a-cli-application ? – JonasCz May 28 '15 at 12:17
  • Conversationally: wouldn't CTRL+C be the exception to the rule? That is what you use if you really-really-really want a program to shutdown, so it would be rather counter-productive if it then automagically came back to life again. – Gimby May 28 '15 at 12:57
  • _"Did you check this: [...]"_ I did not. I didn't search for Ctrl + C because I wanted a more generic solution, that would work for Ctrl +C and other eventually possible ways to terminate the JVM. @Gimby, I asked this question with a similar thought in mind: I wondered if it was possible to run a .jar that would be hard to kill, since every single one I've run so far was apparently very well behaved. – goncalotomas May 28 '15 at 13:38

3 Answers3

1

You can make a cron job for it in linux.

e.g. http://java.dzone.com/articles/how-automatically-recover

This example will show you how to start a tomcat if it crashers.

Rahul Thachilath
  • 343
  • 3
  • 16
1

You can add a shutdown hook that will be run during orderly application shutdown. You would do it like so:

Runtime runtime = Runtime.getRuntime();
runtime.addShutdownHook(new Thread() {
    @Override
    public void run() {
        // save state before exiting and start again
        System.out.println("saving...");
    }
});

However, you should note that this will not cover the case where an external signal kills the process or the JVM otherwise does not shut down in an orderly fashion.

http://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/signals.html has a discussion about the subject of signals in the context of the JVM and you can look at http://en.wikipedia.org/wiki/Unix_signal for a discussion of POSIX signals specifically. Note that even if you implement a native or java signal handler, there are some signals that cannot be handled (e.g. SIGKILL on a Linux/Unix)

pens-fan-69
  • 869
  • 7
  • 10
  • What do you mean by external signal? Does it work for Ctrl+C? Can you please elaborate on that? – goncalotomas May 28 '15 at 13:29
  • 2
    @Aprendiz, Yes it works for Ctrl + C, and and external signal for example could be a "killall -9 java" in linux or a "yes" click on "this application has stopped responding, do you want to force close it ?", or a JVM crash. – JonasCz May 28 '15 at 14:28
  • @Aprendiz http://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/signals.html has a discussion about the subject of signals in the context of the JVM and you can look at http://en.wikipedia.org/wiki/Unix_signal for a discussion of POSIX signals specifically. Note that even if you implement a native or java signal handler, there are some signals that *cannot* be handled (e.g. SIGKILL on a Linux/Unix). – pens-fan-69 May 28 '15 at 14:30
  • I would advise adding that information to the answer itself, just to get a more complete answer. :) I read up on the available signals and a `SignalHandler` is not really what I wanted to do, since I can use the code you suggested along with a `ProcessBuilder`. I tested it and it does in fact work with Ctrl + C. Awesome! – goncalotomas May 28 '15 at 15:59
  • Final question regarding my last question update, how would you do to associate the new Process with a terminal so you can at least see the output? – goncalotomas May 28 '15 at 16:21
  • 1
    If you are using ProcessBuilder to launch the new process, you could use the inheritIO() method (though I haven't personally tested this). – pens-fan-69 May 28 '15 at 16:26
0

be careful there can be a change that there are threads running in your service that will reopen the notification

niek tuytel
  • 189
  • 2
  • 9