【问题标题】:How do I see the full stack trace when I catch an exception捕获异常时如何查看完整的堆栈跟踪
【发布时间】:2016-12-01 11:01:41
【问题描述】:

我的 Java 代码有这个(但不管我是否应该捕获 RuntimeException 我有我的理由)

catch(RuntimeException e) {
    MainWindow.logger.log(Level.SEVERE, InfoMessage.MSG_MUSICBRAINZ_QUERY_SYNTAX_ERROR.getMsg(song.getRecNo(), song.getFile().getName()),e.getCause());
    stats.incUnableToMatchIds();
}

我不明白为什么当异常确实发生时它只会到达这个 catch 块,所以它不能确定异常发生的位置。我使用 e.getCause() 还是 e 没有区别

java.lang.NullPointerException
    at com.jthink.jaikoz.manipulate.UpdateGroupFromMusicBrainzIdsWorker.call(UpdateGroupFromMusicBrainzIdsWorker.java:234)
    at com.jthink.jaikoz.manipulate.UpdateGroupFromMusicBrainzIdsWorker.call(UpdateGroupFromMusicBrainzIdsWorker.java:42)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

如果我删除了这个 catch 块,它会显示完整的堆栈跟踪,这就是我想要它做的,

java.lang.NullPointerException
    at com.jthink.jaikoz.manipulate.classical.MusicBrainzSoundtrackChecker.updateSoundtrack(MusicBrainzSoundtrackChecker.java:37)
    at com.jthink.jaikoz.manipulate.UpdateGroupFromMusicBrainzIdsWorker.call(UpdateGroupFromMusicBrainzIdsWorker.java:152)
    at com.jthink.jaikoz.manipulate.UpdateGroupFromMusicBrainzIdsWorker.call(UpdateGroupFromMusicBrainzIdsWorker.java:42)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

如何使用 catch 中的记录器获取 com.jthink.jaikoz.manipulate.classical.MusicBrainzSoundtrackChecker.updateSoundtrack(MusicBrainzSoundtrackChecker.java:37) 行部分?

编辑

也许正如建议的那样,它是我的记录器,因为如果我添加了

catch(RuntimeException e) { e.printStackTrace(); MainWindow.logger.log(Level.SEVERE, }

我用 e.printStackTrace() 得到了输出 ok

java.lang.NullPointerException
    at com.jthink.jaikoz.manipulate.classical.MusicBrainzSoundtrackChecker.updateSoundtrack(MusicBrainzSoundtrackChecker.java:37)
    at com.jthink.jaikoz.manipulate.UpdateGroupFromMusicBrainzIdsWorker.call(UpdateGroupFromMusicBrainzIdsWorker.java:152)
    at com.jthink.jaikoz.manipulate.UpdateGroupFromMusicBrainzIdsWorker.call(UpdateGroupFromMusicBrainzIdsWorker.java:42)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
01/12/2016 11.18.53:com.jthink.jaikoz.manipulate.Analyser:waitForWorkers:WARNING: Worker:0:Exception:null
java.lang.NullPointerException
    at com.jthink.jaikoz.manipulate.UpdateGroupFromMusicBrainzIdsWorker.call(UpdateGroupFromMusicBrainzIdsWorker.java:235)
    at com.jthink.jaikoz.manipulate.UpdateGroupFromMusicBrainzIdsWorker.call(UpdateGroupFromMusicBrainzIdsWorker.java:42)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

【问题讨论】:

  • e.printStackTrace()?
  • @Andremoniy 您如何将来自printStackTrace 的输出从默认(错误)控制台重定向到您自己的记录器?
  • 或者使用一些记录器并做log.error(e.getMessage(), e)
  • @avi613 引用很重要,因为它向我展示了问题所在,没有它我不知道是什么代码导致了异常,只是有一个 NullPointerException。我使用标准的 Java 日志框架
  • @PaulTaylor 好的,这里可能有一些帮助是您正在使用的记录器实现 (MainWindow) 和引发异常的代码行。

标签: java exception


【解决方案1】:

所以你有一个 NPE。换句话说,您正在调用尚未初始化(即构造)的对象的方法。
有时,解决起来可能会很棘手,因为未初始化的对象可以嵌套在一个嵌套在嵌套的...对象中,并且生成此异常的方法调用可能非常远程。

这是一个假设:如果没有try / catch 块,您没有相同的堆栈跟踪,那么它可能是一个不同的例外。我的意思是:也许您的catch 块本身正在从与try 块中的位置不同的位置生成NPE。这是您的日志记录行建议的:

InfoMessage.MSG_MUSICBRAINZ_QUERY_SYNTAX_ERROR.getMsg(song.getRecNo(), song.getFile().getName()),e.getCause());

那里发生了太多事情!尝试调试这段代码,不管有没有try / catch,检查每个对象。我敢肯定,您会在每种情况下找到不同的 NPE。

关于更多背景知识,NPE 不应发生在生产代码中。您应该注意所有对象(和子对象)都已初始化。
许多最近开发的语言都禁止或找到防止此错误的方法。
请看这个参考:Tony Hoare,后悔发明了null

【讨论】:

  • 是的,这就是问题所在,问题是歌曲变量本身为空,我没有注意到,因为我在本地范围内使用了另一个对 catch 块不可见的歌曲变量
  • 关于 npes,我的代码使用了一些 webservices api,这些 api 有时会更改或中断,我无法控制这些,所以有时会出现我以前无法轻松测试的新问题。此外,在我捕获此类异常的情况下,我的应用程序可以记录并继续,让异常传播到最终用户将毫无意义,对用户没有帮助。
猜你喜欢
  • 2015-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-08
  • 2020-10-03
  • 2020-12-14
  • 2011-08-30
相关资源
最近更新 更多