2012-10-11 12 views
22

に私が追加した動作しませんshutdown hook経由:それは通常は正常に動作しますが、私はEclipseで赤い停止ボタンをクリックしないときシャットダウンフックは、Eclipse

Runtime.getRuntime().addShutdownHook(myShutdownHook); 

。 Eclipseでシャットダウンフックを呼び出す方法はありますか?

+0

質問は2年後に尋ねられた質問に重複して表示されます。 – urir

+0

実際にもう1つは2年前です。あなたはたぶんその年の日(13)を間違って読んでいるでしょう。 – Christoph142

答えて

12

アプリケーションが終了しているため、シャットダウンフックは呼び出されません。

残念ながら、フックが常に呼び出されるようにする仕組みを(Windowsでは少なくとも)提供する方法はありません。呼び出されるかもしれないものですが、保証はありません。

+2

「フックが常に呼び出されるようにするメカニズムを提供する方法はありません」という発言を引用してください。http://docs.oracle.com/javase/7/docs/api/java/lang/ランタイム。html#addShutdownHook(java.lang.Thread)は、 "プログラムが正常に終了する"、または "ユーザ/システム割り込みに応答して仮想マシンが終了された"ときにフック**が実行されることを明確に示しています。 – Pacerier

+1

@ Pacerierそのステートメントは、Javaアプリケーションを呼び出すバッチスクリプトを実行していたコンソールウィンドウを閉じたところで行ったテストに基づいています。ウィンドウを閉じると、シャットダウンフックが呼び出されませんでした。 –

+2

これは、Eclipseからアプリケーションを停止することですが、*正常に終了しないプログラムの例です*。 –

4

あなたが使用して問題を回避することはできません:

if (Boolean.parseBoolean(System.getenv("RUNNING_IN_ECLIPSE")) == true) { 
       System.out.println("You're using Eclipse; click in this console and  " + 
               "press ENTER to call System.exit() and run the shutdown routine."); 
       try { 
         System.in.read(); 
       } catch (IOException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
       } 
       System.exit(0); 
     } 

を参照してください:赤い停止ボタンを強制的にすなわちない優雅に、アプリケーションを殺すので、JVMがあることを知らないHow to get shutdown hook to execute on a process launched from Eclipse

+2

私はすべてのユーザーに環境変数を追加するように要求することはできません。 – urir

+0

少なくとも、デバッグと実験の際の回避策として、私はこのアイデアが好きです。これまでに見つかったこの問題に対する他の回避策よりもはるかに実用的です。 – Nic

0

赤いストップボタンは、アプリケーションを終了させるだけで、Eclipseの開発者によれば、これについては何もできません。これはEclipseのバグトラッカーのissueです。

0

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

5

私が飾ら1でJavaProcessを置き換えることにより、ハックを作った:

IProcess p = launch.getProcesses()[0]; 
    launch.addProcess(new JavaProcessDecorator(p)); 
    launch.removeProcess(p); 

そして、デコレータは関数を終了オーバーライドしています。

public class JavaProcessDecorator implements IProcess { 

private IProcess p; 

public JavaProcessDecorator(IProcess p) { 
    this.p = p; 
} 

private boolean sigkill = false; 

@SuppressWarnings("rawtypes") 
@Override public Object  getAdapter(Class arg)    { return p.getAdapter(arg); } 
... 
@Override public ILaunch  getLaunch()       { return p.getLaunch(); } 
@Override public IStreamsProxy getStreamsProxy()     { return p.getStreamsProxy(); } 
@Override public void   setAttribute(String s1, String s2) {  p.setAttribute(s1, s2); } 
@Override public void   terminate() throws DebugException { 
    if(!sigkill) { 
     try { 
      IDebugIService cs = DirmiServer.INSTANCE.getRemote("main", IDebugIService.class); 
      if(cs != null) cs.modelEvent(new TerminateRequest()); 
     } catch (RemoteException e) { } 
     this.sigkill = true; 
    } else p.terminate(); 
}} 

最初に赤いボタンをクリックすると、優しく終了することをアプリケーションに伝えます。それが動作していない場合は、もう一度赤いボタンをクリックすると、それが殺されます。

-1

フックが機能しているかどうかだけをテストする場合は、トリガーポイントからthrow new RuntimeException()を入力します。 Eclipseからもシャットダウンフックを呼び出す必要があります。

1

私はパーティーに少し遅れていることは知っていますが、このスレッドは助けを求めており、おそらく他の人もそうです。

私たちは同じ問題を抱え、今すぐ追加の停止ボタンを提供するEclipse plugin(Linux版)で解決しました。 私はこれが皆さんのために役立つだけでなく、助けてくれることを願っています:)

関連する問題