Java Programming

【Java】例外エラー発生!!Caused byから真の原因箇所を特定する方法

Gerd AltmannによるPixabayからの画像

こんにちわ。しろです。

前回はStackTraceの見かたや、原因箇所を特定するまでの内容を紹介しました。

今回は、StackTrace中にCaused byが含まれている場合の見かたについてお話しします。

Caused byとは

Caused byは、「~が原因で」という意味です。

StackTrace中にCaused byが含まれている場合、そこから続く情報に例外エラーが発生した真の原因が示されています。

仕組みと見かたさえ分かれば簡単です。

Caused byが出力されるソース

次のソースを実行すると、StackTrace中にCaused by:が出力されます。

このソースは、次の順番でメソッドが呼びだれます。

  • main
  • method01
  • method02

method02では、"method02からスローした例外"というメッセージが設定された例外エラーがthrowされます。

※ここが真の原因箇所となります。

その後、呼び出し元のmethod01にて、例外エラーがcatchされ、新たに例外クラスを生成し、スローします。この時、コンストラクタの第2引数(cause)に、catchした例外クラスを設定しています。

この第2引数に指定した例外クラスが真の原因になります。

最後に、method01の呼び出し元mainにて例外エラーをcatchし、StackTraceを出力する、という流れになります。

Caused byの見かた

次のメッセージは、先ほどのソースを実行した結果、出力される内容です。

java.lang.Exception: method01からスローした例外
at exception/com.shirobetween.Main.method01(Main.java:30)
at exception/com.shirobetween.Main.main(Main.java:13)
Caused by: java.lang.Exception: method02からスローした例外
at exception/com.shirobetween.Main.method02(Main.java:36)
at exception/com.shirobetween.Main.method01(Main.java:25)
… 1 more

前回の見かたに従い、StackTraceの一番上を確認してみます。

at exception/com.shirobetween.Main.method01(Main.java:30)

と出力されていますが、そこは、method01でmethod02からスローされた例外をcatchし、新たな例外クラスをスローしている箇所なので、真の原因とはいえません。

次に、Caused byの一番上を確認します。

at exception/com.shirobetween.Main.method02(Main.java:36)

ここは、method02が例外エラーをスローしている箇所で、真の原因箇所といえます。

このように、StackTrace中にCaused byが含まれている場合は、そこに原因箇所の情報が記されています。

なので、StackTraceを確認する際は、まずはCaused byを探しましょう。

注意点

先ほどのソースを次のように、method01で例外クラスを生成する際に、method02の例外クラスを含めないように修正します。

修正したソースを実行すると、次のメッセージが出力されます。

java.lang.Exception: method01からスローした例外
at exception/com.shirobetween.Main.method01(Main.java:30)
at exception/com.shirobetween.Main.main(Main.java:13)

Caused byの内容が含まれず、真の原因箇所が特定できない内容になっています。

StackTraceは、例外エラー自身がスローされた場所からの追跡情報を出力します。

修正前のソースは、原因となった例外クラスをコンストラクタに指定しているためCaused byに真の原因が出力されます。

修正後のソースは、例外クラスをコンストラクタに指定していないため、真の原因が抜け落ちていて、StackTraceの内容だけでは、追跡できない内容となってしまいます。

このソースは短いのでソースを見ただけで解決はできますが、実際の業務では長くて複雑なソースは当たり前のように存在するため、修正後ソースのような例外処理で実装されている場合、追跡が非常に困難になるので注意しましょう。

また、今回の例では、Caused byを1つだけ出力していますが、複数出力されている場合は、最後のCaused byが真の原因となるので気を付けて下さい。

まとめ

  • Caused byには、発生した例外エラーの原因となる情報出力される。
  • 例外クラスのコンストラクタに、例外クラス設定することで、原因として指定できる。
  • StackTraceを見るときは、まずはCaused byが含まれているかを確認する。
  • Caused byが複数出力されている場合は、最後のCaused byが発生原因となる。

以上となります。

最後まで読んで頂き有難うございます。

参考

19.2.2 スタックトレースの分析方法(その2)

-Java, Programming
-, ,

© 2020 しろブログ