2012-12-06 10 views
5

ライセンス数が限られているライセンスサーバーからライセンスオブジェクトを取得または解放する方法があるライセンス付きAPIを使用しています。私のアプリケーションの冒頭で、私はライセンスを取得するメソッドを呼び出しますが、私はプログラムが終了/突然クラッシュ(例外、SIGTERMなど)がリリースされていることを確認したい。シャットダウンフックはこの問題に近づける最善の方法ですか?Javaアプリケーションを終了する前にコードを確実に実行する方法

+0

「最後に」クローラを意味しましたか? –

答えて

8

で「最後の防御線」を作成します。 JVMがクラッシュしたり、SIGKILLを取得したりすると、終了する前に何かを実行する機会はありません。このシナリオでは、Javaでこれを修正するために何もできません。 (ただし、状況は他の言語でも同じです...)

しかし、JVMが非ダメージスレッドの終了に応答して正常にシャットダウンした場合、System.exit()を呼び出してSIGINTを取得するなど、JVMはシャットダウン・フックの実行を試みます。 Q&Aページとjavadocsには、Javaのシャットダウンフックメカニズムの詳細があります。

finallyのアプローチもオプションですが、問題のスレッドがJVMが終了する前に終了する場合にのみ有効です。 System.exit()が呼び出された場合、またはJVMがシグナルによって終了した場合は、これは発生しません。シャットダウンフックはより多くの状況で機能します。

(私にとって、finallyは、アプリケーション全体ではなく、単一のスレッドでクリーンで実行することです。ただし、アプリケーションが1つのスレッドだけで構成されている場合、または規則的に責任を負うマスタースレッドがある場合シャットダウン... finallyは、アプリケーションクリーンアップの目的に役立ちます。)


真の解決策は、ライセンスを使用して、アプリケーションのインスタンスがそれを解放せずになくなったときにライセンスマネージャが検出できるように、ライセンスのAPIを設定することです。これが可能かどうかは、ライセンスマネージャによって異なります。

3

プログラムがJVMのクラッシュによって終了した場合、呼び出されているものに依存することはできません。

プログラムがJVMに関係しない例外によって終了した場合、try/catch/finallyブロック内のすべてをラップすることができます。 finallyブロック内のコードは、コードが終了する前に実行されることが保証されます。

2

例外の場合、mainの本文をtry/catch/blockにラップすることができます。 SIGTERM信号を処理する場合は、add a shutdown hookとすることができます。ただし、シャットダウンフックは、SIGKILLのような信号に対してトリガされる保証はありません。 Java docから

まれな状況では、仮想マシンがを中止することがあり、それは、きれいにシャットダウンせずに実行している を停止しています。これは仮想マシン が外部で終了した場合、たとえばUnixではSIGKILLシグナル 、Microsoft WindowsではTerminateProcessコールで終了します。たとえば、 が内部データ構造を破壊したり、存在しないメモリ にアクセスしようとすると、ネイティブメソッドが異常終了した場合でも、仮想マシン が中断することがあります。 仮想マシンが異常終了すると、シャットダウンフックが実行されるかどうかについて、 という保証はありません。

1

これは決してSytem.exit()を呼び出さないことで実現します。メインで ()あなたは@thedanハードJVMがクラッシュに関する正しいです

try { 
    startApp(); 
} catch (Exception ex) { 
     // do some logging 
} finally { 
    releaseLicense(); 
} 
関連する問題