2012-01-03 4 views
1

から任意のクラスでログインできるように:ShutdownHookが終了する前にそのロガーを避けるために、どのようにはどのようshutdownHookを想定shutdownHook

class ShutdownHolder extends Thread { 

    public void run() { 
     Logger logger = LoggerFactory.getCoreLogger(ShutdownHolder.class); 
     try { 
     logger.info("Shutdown hook is running..."); 
     doSomething(); 
     logger.info("Shutdown hook end."); 
     } catch(Exception e) { 
     logger.severe("Unexpected ERROR during shutdown", e); 
     } 
    } 
    } 

閉じられていないのですか?

たとえば、doSomething()メソッドは、ログを書き込む他のアクセス可能なクラスのいくつかのメソッドを呼び出すことができます。私はこれらのログをすべてスキップしたくありません。

+0

どういう意味ですか?なぜロガーが閉鎖されるのですか? 'doSomething()'は 'run()'メソッドに戻るはずですね。 – adarshr

+0

http://docs.oracle.com/cd/E17409_01/javase/6/docs/api/java/lang/Runtime.html#addShutdownHook%28java.lang.Thread%29 "これらのサービスには、独自のシャットダウンフックを登録している可能性があり、シャットダウンの過程にある可能性があります。 Loggerは独自のshutdownHookを持っているようです。 – Mik378

答えて

1

反射ハックを除いて、残念なことにこれを行う簡単な方法はありません。 1.6 JDKでは、シャットダウンフックはIdentityHashmapに格納され、保証された順序は提供されません。事実上、シャットダウンフックはそのマップの内部構造に応じてランダムな順序で呼び出されます。

私は反射の面で次のようにしましたが、hookMapが私のために出てきます。あなたがそれを動作させることができれば、あなたはlog4jフックを取り外して、あなたのフックなどの終わりに手動で呼び出すことができるかもしれません。しかし

Class<?> clazz = Class.forName("java.lang.ApplicationShutdownHooks"); 
Field field = clazz.getDeclaredField("hooks"); 
field.setAccessible(true); 
@SuppressWarnings("unchecked") 
Map<Thread, Thread> hookMap = (Map<Thread, Thread>) field.get(null); 

は、私は強くシャットダウンフック以外の何かを行うことをお勧めします。 mainが終了する前に自分のフックを呼ぶのはどうですか?私たちにとっては、Springと、DisposableBeanというパターンを多用しています。これらの豆です。クラスがインスタンス化されたときと逆の順序で呼び出されるので、ロガーに依存するものはすべてシャットダウン時にロガーを持ちます。

これが役に立ちます。

関連する問題