Java shutdown hook not launching my Process

311 views Asked by At

I'm trying to give to my app self update ability. It download an JAR from my website and save it as myapp.jar.new.

After that, I want to launch a command to delete the current version and rename the new one.

This is my code (see the notes):

public void applyUpdateAndRestart() {
    Runtime rt = Runtime.getRuntime();
    rt.addShutdownHook(new Thread(() -> {
        try {
            String updateCmd = "restart.cmd";
            try (PrintStream ps = new PrintStream(new FileOutputStream(updateCmd))) {
                ps.println("@echo off");
                // wait for a while to the main process closes and the "myapp.jar" to be writable
                ps.println("ping 127.0.0.1 -n 2 > nul"); 
                ps.println("del /q myapp.jar.old");
                ps.println("move myapp.jar myapp.jar.old");
                ps.println("move myapp.jar.new myapp.jar");
                ps.println("java -jar myapp.jar");
            }

            ProcessBuilder p = new ProcessBuilder();
            p.command("cmd", "/c", updateCmd);

            System.out.println("Before apply update");

            p.start(); // this does not launch

            System.out.println("After apply update"); // this prints!
        } catch (Throwable e) {
            e.printStackTrace(); // this does not occurs!
        }
    }));
    System.exit(0);
}

Why my update.cmd does not start?

3

There are 3 answers

0
Beto Neto On BEST ANSWER

Solved with this approach:

  • After download my jar to new-myapp.jar, I launch it with an special argument like this: java -jar new-myapp.jar --do-update (running the new jar will unlock the current to be overwritten)
  • My main mehtod intercept the argument --do-update who applies the new jar to current (copy new-myapp.jar myapp.jar).
  • After the new jar was copied, It launches itself again using the overwritten jar (java -jar myapp.jar)

I think that Klitos comment can solve my problem too, but I solved implementing my previous approach.

On the approach of the question the problem was that the cmd /c haven't a console window allocated. Changing the command to cmd /c start solve the problem too because the start command allocate a new console window.

0
Nikolay Lagutko On

My idea - since you just call start() for process and finish the shutdown hook - the process dies with your main java process. Try to call Process.waitFor() to have you shutdown hook thread waiting until external process finished.

0
Alex Favieres On

I think that you can't do it like you want. You want to remove the jar of the application but the app is running and therefore could not be removed.

My suggestion is use a launcher.cmd that look for a new.jar if it finds it remove old.jar and rename new.jar and THEN launch java -jar old.jar.