2

In many software, after we make any changes, the software has to be restarted for the changes to take effect, and sometimes, there is an option to restart the software automatically. How can I implement this in Java?
This is what I have tried:

int o = JOptionPane.showConfirmDialog(
                                frame,
                                "<html>The previously selected preferences have been changed.<br>Watch must restart for the changes to take effect.<br> Restart now?</html>",
                                "Restart now?", JOptionPane.YES_NO_OPTION);
                if(o == JOptionPane.YES_OPTION) {

                    try {
                        Process p = new ProcessBuilder("java", "Watch").start();
                    } catch(IOException e) {
                        e.printStackTrace();
                    }
                    frame.dispose();

However, this doesn't seem to work. The application just terminates. What am I missing here? Thanks in advance!

JavaNewbie_M107
  • 2,007
  • 3
  • 21
  • 36
  • Try an absolute path instead of just "Watch". – Sebastian Jun 12 '13 at 13:31
  • You mean add the CLASSPATH? – JavaNewbie_M107 Jun 12 '13 at 13:31
  • Try starting your program from the command line -> Put exactly this in to the `ProcessBuilder`. I once had the problem that environment variables like "PATH" were not loaded with the ProcessBuilder, so "java" was not recognized. There's a way to do this, though. I don't remember... – Sebastian Jun 12 '13 at 13:35
  • 1
    This reminds me of the old joke "You have moved the mouse. Windows needs to be restarted for the changes to take effect." - on a serious note, while it may be easier to code, the user surely prefers not to have to restart just to make some config changes active. – Durandal Jun 12 '13 at 13:40
  • @JavaNewbie_M107 Brian Roach's answer is the one you want. Look there for the top answer. – Sebastian Jun 12 '13 at 13:43

3 Answers3

0

This looks interesting: Make your application restart on its own

Basically, you create a script to run your app. In your app, if the user choses to restart, a restart file is created, then the app exits. Upon exiting, the startup script checks for the existence of a restart file. If exists, call the app again.

splungebob
  • 5,357
  • 2
  • 22
  • 45
0

I think this is hard using just the facilities of the JVM alone.

I've never done this, but if you really want to terminate the whole JVM in which your current application is running and start a completely new instance of it, I would probably try something along these lines:

  1. From your main application thread, start a shell script / batch file (e.g. using Runtime.getRuntime().exec("...")` that does the following steps:

    • Forks or uses some other system facility of starting the next step(s) in the background.
    • Maybe wait some time so you can be sure the old instance is dead. Or wait until some kind of PID file or similar thing is removed telling you that the old instance is gone.
    • Start a new JVM with your applications main class, probably giving it some command line argument or setting some system property to notify this new instance that it is in fact, an automatically restarted instance (so it can react to this e.g. by continuing where your originally left off).
  2. In parallel to step 1 in your first main app instance, maybe wait a small amount of time (to make sure the background stuff is actually executed) and call System.exit(0); or some other method of shutting down.

Maybe there is a simpler way, it's just the first way that I could think of.

David
  • 1,359
  • 1
  • 13
  • 20
0

What about the next:

public static void main(final String[] args) {
    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            buildAndShowGui(args);
        }
    });
}

public static void buildAndShowGui(final String[] args) {
    final JFrame frame = new JFrame("Window");
    frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
    frame.setSize(100, 400);
    frame.setLayout(new FlowLayout());
    JButton button = new JButton("Click!");
    button.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            int option = JOptionPane.showConfirmDialog(frame, "Restart?");
            if (option == JOptionPane.YES_OPTION) {
                frame.dispose();
                restart(args);
            }
        }
    });
    frame.add(button);
    frame.setVisible(true);
    frame.toFront();
}

public static void restart(String[] args) {
    main(args);
}
Paul Vargas
  • 41,222
  • 15
  • 102
  • 148