2017-09-15 6 views
1

私は自分のアプリの自己更新機能を提供しようとしています。 私のウェブサイトからJARをダウンロードし、myapp.jar.newという名前で保存してください。Javaシャットダウンフックがプロセスを起動していません

その後、現在のバージョンを削除して新しいバージョンの名前を変更するコマンドを起動します。

これは、(ノートを参照してください)私のコードです:

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); 
} 

update.cmdが起動しないのはなぜ?

+1

シャットダウンスレッドによってスローされた例外はすべて抑止され、出力は作成されません。私はIOExceptionだけでなく、すべての例外をキャッチし、結果を表示します。おそらく、cmdを呼び出すときに何かが間違っている可能性があります。 –

+0

@ MarkusFischer Throwableもキャッチしようとしましたが、発生しません。残念ですが、2番目のsysoutが印刷されます! –

+1

出力は 'p.start()'によって返された 'Process'オブジェクトの' InputStream'に束縛されているので、作成された子プロセスの出力は表示されません。 'ProcessBuilder.inheritIO()'を使ってみてください。 –

答えて

1

このアプローチで解決:new-myapp.jarに私のjarファイルをダウンロードした後、私はこのような特別な引数を指定して、それを起動

  • java -jar new-myapp.jar --do-update(新しいjarファイルを実行すると上書きされるために、現在のロックを解除します)
  • マイmain mehtodは、現在の(copy new-myapp.jar myapp.jar)に新しいjarを適用する引数--do-updateを傍受します。
  • 新しいjarファイルがコピーされた後、それは上書き瓶(java -jar myapp.jar)を使用して、もう一度自分自身を起動する

私はKlitos commentがあまりにも私の問題を解決することができると思いますが、私は私の以前のアプローチを実施し解決しました。

問題のアプローチでは、cmd /cにコンソールウィンドウが割り当てられていないという問題がありました。コマンドをcmd /c startに変更すると、startコマンドが新しいコンソールウィンドウを割り当てるため、この問題も解決します。

0

私の考え方 - プロセスのstart()を呼び出してシャットダウンフックを終了するだけで、プロセスはメインのJavaプロセスで終了します。 Process.waitFor()を呼び出して、外部プロセスが終了するまでスレッドをシャットダウンするようにしてください。

0

あなたが望むようにできないと思います。アプリケーションのjarファイルを削除したいが、アプリケーションが実行されているため削除できませんでした。

old.jarを削除してnew.jarの名前を変更し、THENがjava -jar old.jarを起動すると、new.jarを検索するlauncher.cmdを使用します。

関連する問題