3

以下のコードで例外が再スローされると、元のスタック トレースは保持されません。

例外は 148 行目でスローされ、150 行目で再スローされます。再スロー後、150 行目は例外の指定されたソースです。

元のスタック トレースを保持するにはどうすればよいですか?

コード:

    try {

        content = (InputStream) conn.getContent(); //line 148

    } catch (IOException e) {

        throw new RuntimeException(e); //line 150

    }

元のスタック トレース:

 (java.lang.StackTraceElement[]) [sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source), java.net.URLConnection.getContent(Unknown Source), com.mycompany.myapp.client.services.impl.AbstractClientService.getResponseEle(AbstractClientService.java:148), com.mycompany.myapp.client.services.impl.AbstractClientService.getResponseEleWithCheck(AbstractClientService.java:162), com.mycompany.myapp.client.services.impl.AbstractClientService.getResponseEleWithCheck(AbstractClientService.java:158), com.mycompany.myapp.client.services.impl.InfoQueryClientServiceImpl.getFileOnTmpList(InfoQueryClientServiceImpl.java:84), com.mycompany.myapp.client.myappClient.getFileOnTmpList(myappClient.java:196), com.mycompany.myapp.client.model.Model.updateStudyInfos(Model.java:96), com.mycompany.myapp.client.model.Model.instantiateSingleton(Model.java:46), com.mycompany.myapp.applet.MainApplet.addMainPanel(MainApplet.java:106), com.mycompany.myapp.applet.MainApplet.createUIPanel(MainApplet.java:76), com.mycompany.myapp.applet.MainApplet.init(MainApplet.java:58), com.sun.deploy.uitoolkit.impl.awt.AWTAppletAdapter.init(Unknown Source), sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source), java.lang.Thread.run(Unknown Source)]

再スロー後のスタック トレース:

 (java.lang.StackTraceElement[]) [com.mycompany.myapp.client.services.impl.AbstractClientService.getResponseEle(AbstractClientService.java:150), com.mycompany.myapp.client.services.impl.AbstractClientService.getResponseEleWithCheck(AbstractClientService.java:162), com.mycompany.myapp.client.services.impl.AbstractClientService.getResponseEleWithCheck(AbstractClientService.java:158), com.mycompany.myapp.client.services.impl.InfoQueryClientServiceImpl.getFileOnTmpList(InfoQueryClientServiceImpl.java:84), com.mycompany.myapp.client.myappClient.getFileOnTmpList(myappClient.java:196), com.mycompany.myapp.client.model.Model.updateStudyInfos(Model.java:96), com.mycompany.myapp.client.model.Model.instantiateSingleton(Model.java:46), com.mycompany.myapp.applet.MainApplet.addMainPanel(MainApplet.java:106), com.mycompany.myapp.applet.MainApplet.createUIPanel(MainApplet.java:76), com.mycompany.myapp.applet.MainApplet.init(MainApplet.java:58), com.sun.deploy.uitoolkit.impl.awt.AWTAppletAdapter.init(Unknown Source), sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source), java.lang.Thread.run(Unknown Source)] 
4

5 に答える 5

3

コードは元の例外を再スローしませんがRuntimeException、作成時にスタック トレースが満たされた新しいインスタンスをスローします。

Throwable.getCause().getStackTrace()RuntimeException をキャッチするか、RuntimeException をスローする前に、RuntimeException のスタック トレースを元の例外から 1 つに設定するときに、ether を呼び出すことができます。

于 2012-11-15T10:51:43.983 に答える
2

「問題」は、例外を再スローしていないことです。むしろ、新しい例外をスローしています。本当に次のような例外を再スローする場合:

try {
    content = (InputStream) conn.getContent();
} catch (IOException e) {
    throw e;
}

スタックトレースが保持されていることがわかります。

また、最新のJVMで使用する場合はThrowable.printStackTrace()、連鎖例外とその(一意の)スタックフレームが表示されます。つまり、元の例外からの情報が保持されます。


ある例外から別の例外にスタックトレースをつなぎ合わせる方法があります。

try {
    content = (InputStream) conn.getContent();
} catch (IOException e) {
    RuntimeException re = new RuntimeException(e);
    re.setStackTrace(e.getStackTrace());
    throw re;
}

しかし、個人的にはこれは良い考えではないと思います。の行番号RuntimeExceptionは元の例外と同じになりましたが、接続オブジェクトの異常な状況がRuntimeException発生し、コードがこれを実行できないと言っている場所をスローしているように見えます。通常の方法で例外をチェーンし、チェーンされた例外のスタックトレースを正しく読み取るようにプログラマーに任せる方がよいと思います。

于 2012-11-15T10:43:13.460 に答える
0

元のスタックトレースのみが必要な場合は、キャッチしないでください。一方、何らかの理由でランタイム例外にラップされたと思います。を使用して、ランタイム例外から元の例外を取得できます。getCause()

于 2012-11-15T10:40:48.723 に答える
0

スタックトレースが保持されます。

から原因をRuntimeException取得し、そこからスタックトレースを取得して元を取得する必要があります。

この機能は、例外チェーンと呼ばれます。

于 2012-11-15T10:41:51.873 に答える
0

元のスタック トレースを取得するには、原因となった Throwables のリファレンスに従う必要があります。例えば

public static StackTraceElement[] getCausingStacktrace(Throwable throwable) {
  if (throwable == null) {
    throw new NullPointerException();
  }
  while (throwable != null) {
    throwable = throwable.getCause();
  }
  return throwable.getStacktrace();
}
于 2014-11-22T11:20:06.360 に答える