2017-11-02 36 views
1

JavaFXアプリケーションを使用して、別のプロセス(updater executable)を実行して終了する必要があります。 私はProcessBuilder.command()を使って別のプロセスを実行しています。サブプロセスが!isAlive()になると、プロセスが完全に実行されます。その後、Window.getWindows().forEach(::dispose)System.exit(0)を実行してアプリケーションを終了しようとしています。JavaFXアプリケーションは、System.exit()の後に終了しません。

System.exit(0)を呼び出した後、アプリケーションがハングしますが、別のプロセスが実行されていない場合、アプリケーションは正しく終了します。

"JavaFXアプリケーションスレッド" #32 PRIO = 5 os_prio = 0 TID = 0x000000001f4fe000 NID = 0x44d0はObject.waitにおける() [0x0000000023f4d000]のJava:ここ

はメインスレッドのスタックトレースの一部です。 lang.Thread.State:java.lang.Object.wait(ネイティブメソッド)のawlting(オブジェクト モニタ) java.lang.Thread.join(Thread.java:1252) - locked < 0x00000006c21ac608> .lang.Thread)を でjava.lang.Thread.join(Thread.java:1326)に設定します。java.lang.ApplicationShutdownHooks.runHooks(ApplicationShutdownHooks.java:106) java.lang.ApplicationShutdownHooks $ 1.run(ApplicationShutdownHooks.java:46) java.lang.Shutdown.sequenceでjava.lang.Shutdown.runHooks(Shutdown.java:123)で で(Shutdown.java:167) java.lang.Shutdown.exit(Shutdown.java:212) - ロックされた< 0x00000006c2148fb8>(java.lang.Class.Shutdown)、java.lang.Runtime.exit(Runtime.java:109) ) java.lang.System.exit(System.java:971)で

そこで一部ApplicationShutdownHooks完了するためのアプリケーションを待機です。 アプリケーションに2つのフックが追加されましたが、削除した後も、stacktraceは同じままです。

暗黙的にどのようなフックを追加できますか?サブプロセスが終了する前に別のプロセスを別の方法で実行して終了する必要があるかもしれませんか?

UPD:このアプリケーションは実際には完全なJavaFXアプリケーションではなく、JavaFX部分を含むAWTアプリケーションです。

答えて

0

アプリケーション構造に問題がありました。 実際にJavaFXコンポーネントを手動で起動したSwing/AWTアプリケーションでした。したがって、Platform.exit()またはSysten.exit(0)が呼び出されたとき、AWTウィンドウはアクティブのままであり、アプリケーションが完全に終了するのを防ぎます。 は、この場合、適切に活性AWTウィンドウを配置した後Platform.exit()を呼び出す必要があった:

window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
window.dispose(); 
Platform.exit() 

及びアプリケーションのJavaFXの部分を閉じPlatform.exit()を呼び出しより。

4

あなたが使用する必要があるのJavaFXでアプリケーションを終了するにはどのようなもの:

Platform.exit() 

、このメソッドを使用しますが(停止し、すべてのクロージングメソッドを呼び出すアプリケーションを行います)たとえば、あなたはこれについての詳細を見ることができますここをクリックしてください:Application JavaFX 8

問題の原因となっているコードの部分を共有しない場合、これがあなたのケースを助けるかどうかをご覧ください。

+0

JavaFXアプリケーションで 'System.exit'が許可されていないという文書はありません。あなたが投稿したリンクは、実際にはライフサイクルの一環としてSystem.exit()について話しています。 – Thirler

+0

Platform.exit()を使用する必要があるとは言わず、使用することをお勧めします。 System.exit()のみを他のJavaアプリケーションと同じように使用できます。 Platform.exit()はよりクリーンなexit()メソッドを持ち、終了する前にすべての問題を派生スレッドのように解決する必要があります。 – LMiranda

2

あなたのアプリケーションはまだすべてのシャットダウンフックが完了するのを待っていますが、まだフックがあると思います。

runHooksのメソッドは、アプリケーションの終了時に自動的に実行されます。そして、アプリケーションは完了すると終了します(これ以外のクリーンアップもあります)。以下のコードを参照してください。

static void runHooks() { 
    Collection<Thread> threads; 
    synchronized(ApplicationShutdownHooks.class) { 
     threads = hooks.keySet(); 
     hooks = null; 
    } 

    for (Thread hook : threads) { 
     hook.start(); 
    } 
    for (Thread hook : threads) { 
     try { 
      hook.join(); 
     } catch (InterruptedException x) { } 
    } 
} 

各フックは起動されていないThreadです。シャットダウンすると、すべてのスレッド(hook.start())が開始され、すべてのスレッドが完了または終了するまで待ちます(hook.join())。

stacktraceは、完了していないshutdownhookスレッドがあることを示しています。どのように見つけるかは次のとおりです。

Thread.join()方法はthisに同期され、「ロック」の行は、Threadオブジェクトが問題であるかを示します:

at java.lang.Thread.join(Thread.java:1252) 
    - locked <0x00000006c21ac608> (a java.lang.Thread) 
    at java.lang.Thread.join(Thread.java:1326) 

この番号は、オブジェクトの一意の番号は(私は仮想メモリアドレスを考える)であります。この番号は、アプリケーションの完全なスレッドダンプになければなりません。そうでない場合は、デバッガを使用して、すべてのシャットダウンフック(java.lang.ApplicationShutdownHooks#hooks)を含むセット内のオブジェクトを見つけることができます。

この後、このスレッドを見れば、それが何を待っているかを見ることができます。

ご使用のライブラリによっては、自分のフックだけでなく、shutdownhooksが追加されている可能性があります。

関連する問題