2009-04-22 31 views
3

私は大きな、包括的なキャッチブロックのすべてのエラーをキャッチするスレッドを持っています。私はこれを実行して、私のアプリケーションで予期されたエラーだけでなくエラーを報告することができます。 My Runnableは次のようになります。NullPointerExceptionがキャッチブロックにキャッチされないのはなぜですか?

public final void run() 
{ 
    try 
    { 
     System.out.println("Do things"); /* [1] */ 

     doUnsafeThings(); 
    } 
    catch (Throwable t) 
    { 
     System.out.println("Catch"); /* [2] */ 

     recover(); 
    } 
    finally 
    { 
     System.out.println("Finally"); /* [3] */ 
    } 
} 

NPEがThrowableキャッチブロックによって捕捉されることが予想されます。代わりに、[2]の出力は印刷されず、[3]も出力されません。 [1]の出力が印刷されます。私は、コンソール上で入手できますか何

は、この次のとおりです。地球上の

Uncaught exception java/lang/NullPointerException. 

ここで何が起こっているの?

私はJ2MEを使用していますが、これはSunのWTK v2.5.2エミュレータで実行されています。

私はそれをJVM実装ドッジネスにすることを嫌いますが、私は何かが欠けていると感じるのを助けることができません。 (例えば、コードは明らかに私の生産コードから変更されているので)runメソッドにブロックし、最後に/何ものtry/catchの外ではありません疑いを回避するために

  • を明確にするために

  • これらのブロックの先頭にはSystem.out.printlnがあります。これらのコンソールステートメントに続くものは重要ではありません。
+0

[1]の出力は表示されていますか? –

+0

はい、[1]が表示されます。 – izb

+5

ああ、あなたのサインをすることはできますか、Mr. Skeet? :P – izb

答えて

6

答えは私がばかだと分かります。私は何がうまくいかなかったのか説明したいが、単にそれを「バグのひとつ」と呼んでみよう。

私は、実行可能ファイルを実行したスレッドがカスタムスレッドクラス(いくつかのNokiaのバグを取得する)であることを一時的に忘れていました。それはrun()と呼ばれ、canWait()メソッドの呼び出しの間に繰り返し呼び出されました。

canWaitメソッドが失敗の原因であり、実行に失敗していませんでした。それを打開するために、私はコンソール視力を失い、私の疑問の中でイベントのシーケンスを間違って誤って引用していました。

+1

私たちに知らせてください:) –

+1

知りたい知りたい。私たちはすべて骨が折れてしまった。 –

+4

私は、実行可能ファイルを実行したスレッドがカスタムスレッドクラス(いくつかのNokiaのバグを回避する)であることを一時的に忘れていました。 'canWait()'メソッドの呼び出しの間にrun()を繰り返し呼び出しました。 canWaitメソッドは失敗の原因であり、実行はまったく失敗していませんでした。それを打開するために、私はコンソール視力を失い、私の疑問の中でイベントのシーケンスを間違って誤って引用していました。 – izb

0

他のコードによってスレッドが強制終了される可能性はありますか?通常、finallyブロックは、スレッドがSystem.exit()などで異常終了しない限り、常に実行されます。

+0

残念ながら、これは不可能です。システムは終了せず、コードはCLDC 1.0(基本的にJava APIのサブセット)用に構築されています。つまり、スレッドを終了する方法はありません。これはAPIの一部ではありません。スレッドはrun()が終了すると終了します。 – izb

+0

スレッドが実際に終了していることを確認できますか?スレッドはまだ生存していますが、どこかの例外のためにブロックされている可能性はありますか?そして、外部から死んでいるように見えますか? –

4

これは野生の推測ですが、物事を説明します。ので、私の推測では、それはそれはtryブロックとは異なるロガーを使用しています何かを、ログに記録する前に、あなたのキャッチ(または最終的には)ブロックが何かをやっているのどちらかということである -

明らかにあなたのコードがあること、実際にではありません。いずれにしても、キャッチブロックまたは最終ブロックが例外をスローしていると思われます。

私はあなたがスタックトレースがあるとしていない...

EDIT:それはちょうどSystem.out.printlnだ場合オーケー、それは強打行くかもしれない引数で何かありますか?たとえば、

catch (Throwable t) { 
    // Will go bang if t.getCause() returns null 
    System.out.println(t.getCause().getMessage()); 
} 

の場合は非常に奇妙です。

tryブロック内のログ行から実際にどのくらい離れているか知っていますか?

+0

スタックトレースはありません(キャッチできません)。私の質問への私の更新はちょうどあなたの答えのいくつかを解決します。いずれかのロギングフレームワークはありません。単にSystem.out.printlnです。 – izb

5

試行錯誤が必要なような音がします。私が提案してもよい:

try { 
    doEvilStuff(); 
} catch (NullPointerException ex) { 
    System.out.println("NPE encountered in body"); 
} catch (Throwable ex) { 
    System.out.println("Regular Throwable: " + ex.getMessage()); 
} finally { 
    etc... 
} 

のNullPointerExceptionの明示的なキャッチを有することにより例外がtryブロックやキャッチ/ finallyブロック内からであれば、それは明らかになるはずです。

2

あなたのコードを見ると、recover()が例外をスローしているようですので、Jonによって与えられたアドバイスはそれに従うのが良いでしょう。

私たちにスタックトレースを与えた場合、より良いヘルプが得られるかもしれません。私は例外をキャッチしようとすると

私はこのような何か:

try { 
    doSomethingBad(); 
} catch(Exception e) { 
    try { 
     LogException(...); 
    } catch(Exception e) {}  
} finally { 
} 

を私は巣の例外のが好きではありませんが、私は私のcatchブロックを投げた例外を好きではありません。

0
  • コード内の正しい場所を確認してもよろしいですか? つまり、スタックトレースを保護しているdoUnsafeThings()ブロックですか?

  • ビルドメソッドに問題があり、古いバージョンのコードをデバッグしている可能性がありますか?

0

doUnsafeThings()にいくつかのログを追加するだけです。そのメソッドが期待どおりの動作をしているかどうかを確認してください(例えば、try catchを最後に実行して何かをログに記録するなど)

1

通常、NullPointerExceptionをキャッチするのは悪い習慣です。最後は許容され、これら3つの状況のうち

The program contains a null pointer dereference. Catching the resulting exception was easier than fixing the underlying problem. 
The program explicitly throws a NullPointerException to signal an error condition. 
The code is part of a test harness that supplies unexpected input to the classes under test. 

プログラマは、通常、3つの状況下ではNullPointerExceptionをキャッチ。

Catch NullPointerException

関連する問題