4

:Javaブロックでは例外をスローしてはならないことを知っfinallyています。そうしないと、[非常に、非常に、非常に]悪い習慣になります。
私は、すべての例外を処理し(たとえば、ログに記録するか無視する)、それらが伝播するのを防ぐために内部を使用する必要があることを知っています。Java 7のThrowableにメソッドがあることは知っています が Java5と6をターゲットにしています。try-catchfinally
getSuppressed

問題:Javaでは、try-finally例外(名前はA)がブロックによってスローされた場合try、制御はfinallyブロックに到達します(例外がない場合はブロックにも到達しますが、この質問では面白くありません)。次に、finallyブロックが例外をスローすると(名前はB)、例外Aは抑制されるか、マスク/飲み込まれ、例外Bが呼び出し元に伝播されます。

質問:ある例外が別の例外によって抑制されている状況を何らかの方法で検出し、最初の例外をログに記録/記録できますか?
...特定の例外がスローされた理由を推論し、実際に何が起こったのかわからないことに多くの時間を費やしました。

理論的根拠:問題のあるtry-finallyブロックはライブラリにコード化されていることが多いため(現在はHibernateでした)、変更することはできません。

ソリューションの制約:最初に述べたように、考えられるソリューションはJava 7で中継するべきではありませんが、一方で、実稼働グレードである必要はありません(そうすることはボーナスになります)。AOPはここでのオプションです。

( 「開発にJava7を使用する」のような些細な答えを投稿しないでください:)

4

2 に答える 2

1

私が思う問題は、AOPを使用しても、例外消費プロセスをインターセプトできないことです。AOPを使用すると、たとえば、作成されたすべての例外をキャプチャできますが、それらがいつ消費されたかを知ることはできません。

例えば:

try {
    ...
} catch (Exception e) {
    log.boom("Ouchies happened here", e);
}

すべての例外が再スローされるわけではありません。

ただし、特定のレベルでは、呼び出し元がそれらを処理できるように、最終的にほとんどの例外がスローされます。

したがって、とにかく「リーク」例外が発生する可能性が高いことを考えると、ゲームは「リーク」例外を見つけようとすることです。

AOPを使用すると、作成時に各例外を削除することができます(例外レベルでこれを実行できるか、個々のクラスレベルで実行する必要があるかにかかわらず、実際にはAOPに精通していません。場合)。

作成された例外をキャプチャしたら、AOPを介してメソッド呼び出しのラッピングを開始します。これを行うと、メソッドによってスローされた例外をキャプチャできます。

したがって、少しの作業で、メソッドから戻るときに、a)どの例外が作成され、b)どの例外がスローされたかがわかります。メソッドから返された例外の「原因」ツリーをたどると、「このメソッドによって作成された例外」リストからこれらを除外できます。残りはリークです。

理想的には、少し分析した後、どれが単にスローされないか(ただし、他の方法で処理されるか)、どのブロックがfinallyブロックによって実際にシャドウイングされるかを特定できるようになります。

それは不完全であり、間違いなくプロダクションでは使用しません(レコーディングなどのすべての競合状態に多くの作業を費やす必要があります。この種の作業でやりたいよりも多くの作業を行う必要があります。率直に言って、デバッグの)。ただし、特にクラスの小さなドメイン全体で控えめに使用すると、探している情報が得られる場合があります。

于 2011-03-30T21:51:43.943 に答える
0

「ExceptionCheck()」という名前のJNIメソッドがあります。これは、当然のことながら、保留中の例外をチェックします。ネイティブメソッドの途中で呼び出すと、JNIメソッドが実際にスローされる前に戻るのを待っている例外が、以前の呼び出しでスローされたかどうかを確認できます。最終的にネイティブメソッドを呼び出してから、ExceptionCheckを使用して、保留中の例外があるかどうかを確認してみてください。そうなるかどうかはわかりませんが、試してみる価値はあると思います。

于 2011-03-30T21:51:24.930 に答える