こんにちわ。しろです。
前回はStackTraceの見かたや、原因箇所を特定するまでの内容を紹介しました。
今回は、StackTrace中にCaused byが含まれている場合の見かたについてお話しします。
Caused byとは
Caused byは、「~が原因で」という意味です。
StackTrace中にCaused byが含まれている場合、そこから続く情報に例外エラーが発生した真の原因が示されています。
仕組みと見かたさえ分かれば簡単です。
Caused byが出力されるソース
次のソースを実行すると、StackTrace中にCaused by:が出力されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
package com.shirobetween; public class Main { /** * エントリポイント. * @param args 引数. */ public static void main(String[] args) { try { method01(); } catch (Exception e) { e.printStackTrace(); } } private static void method01() throws Exception { try { method02(); } catch (Exception e) { // ★ポイント:コンストラクタに、method02からスローされた例外クラスを設定. throw new Exception("method01からスローした例外", e); } } private static void method02() throws Exception { throw new Exception("method02からスローした例外"); } } |
このソースは、次の順番でメソッドが呼びだれます。
- 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の例外クラスを含めないように修正します。
1 2 |
throw new Exception("method01からスローした例外"); |
修正したソースを実行すると、次のメッセージが出力されます。
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が発生原因となる。
以上となります。
最後まで読んで頂き有難うございます。