如何阻止堆栈跟踪在日志中截断

SCd*_*CdF 68 java exception stack-trace

在Java日志中很多次我会得到类似的东西:

Caused by: java.sql.BatchUpdateException: failed batch
    at org.hsqldb.jdbc.jdbcStatement.executeBatch(jdbcStatement.java:1102)
    at org.hsqldb.jdbc.jdbcPreparedStatement.executeBatch(jdbcPreparedStatement.java:514)
    at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:242)
    ... 113 more
Run Code Online (Sandbox Code Playgroud)

有谁知道如何显示完整的堆栈跟踪(即显示其他113行)?


Throwable 的JavaDocs(适用于Java 7)对发生的事情有一个非常详细的解释.

Cow*_*wan 68

当你看到'... 113 more'时,这意味着'由'引发的异常的剩余行与父异常的那一点上的剩余行相同.

例如,你会有

com.something.XyzException
  at ...
  at ...
  at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:242)
  at ... <the other 113 lines are here>...
Caused by: <the above>.
Run Code Online (Sandbox Code Playgroud)

两个堆栈跟踪'遇见'在AbstractBatcher.executeBatch,第242行,然后在向上调用跟踪上与之相同,与包装异常相同.

  • @TomBrito你看到了完整的堆栈跟踪 - 你有两个例外,一个在另一个里面.如果内(包装)异常的堆栈跟踪为ABCDEFG,而外层的异常的堆栈跟踪ABCZ,然后你就会看到OuterException与"引发的"与堆栈跟踪"GFEDC的InnerException堆栈跟踪ZCBA,......"再多2个'".另外两个是A和B,来自外部堆栈跟踪,为简洁起见,省略了它们. (22认同)
  • 什么?原因和包装异常一样吗?我不明白...课程应该显示问题所在的行,以及截断堆栈跟踪时未显示的内容。我遇到这个问题,想了解这个答案,如果有人可以重新表述它......谢谢!顺便说一句,这个答案似乎没有显示如何打印完整的堆栈跟踪。 (2认同)
  • 这个答案是不正确的。我绝对遇到过其余行不相同的情况。在这种情况下,解决方案是通过使用 -XX:MaxJavaStackTraceDepth VM 选项来增加堆栈跟踪的最大深度,正如 Nikita Koksharov 在下面指出的那样。 (2认同)

小智 20

Apache的Commons Lang提供了一个很好的util方法ExceptionUtils.printRootCauseStackTrace(),它打印嵌套的堆栈跟踪'颠倒'.结果更加直观.

如果你看到printStackTrace()方法中原始文件旁边的结果,那么"113多条"线的位置就会很清楚.


Nik*_*rov 15

增加-XX:MaxJavaStackTraceDepthJVM选项。

  • 为什么这会被低估?这正是答案。设置为 -1 以获得无限深度。 (4认同)

Kev*_*ler 13

我喜欢这里的例子:

HighLevelException: MidLevelException: LowLevelException
         at Junk.a(Junk.java:13)
         at Junk.main(Junk.java:4)
 Caused by: MidLevelException: LowLevelException
         at Junk.c(Junk.java:23)
         at Junk.b(Junk.java:17)
         at Junk.a(Junk.java:11)
         ... 1 more
 Caused by: LowLevelException
         at Junk.e(Junk.java:30)
         at Junk.d(Junk.java:27)
         at Junk.c(Junk.java:21)
         ... 3 more
Run Code Online (Sandbox Code Playgroud)

基本上在源代码中,main调用function a它调用function b它调用......这就要求function e. Function e抛出一个LowLevelException导致函数c捕获LowLevelException并抛出一个MidLevelException(将LowLevelException实例包装在实例内部MidLevelException.Exception该类有一个能够接受不同异常的构造函数,包装它).这会导致函数a捕获MidLevelException并抛出一个HighLevelException现在包含前两个Exception实例的函数.

如其他答案所述,堆栈跟踪并未真正截断,您将看到完整的堆栈跟踪.将.. .3 more在我的例子是存在的,因为它会另有多余的.如果你想要多余并浪费输出线,.. 3 more可以用

at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
at Junk.main(Junk.java:4)
Run Code Online (Sandbox Code Playgroud)

但是没有必要输出这三行,因为它们已经暗示了.