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


73

在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

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


Throwable的JavaDocs(用于Java 7)对正在发生的事情有非常详细的解释。

Answers:


70

当您看到“ ... 113更多”时,表示“由...引起的”异常的其余行与父异常的该点之后的其余行相同。

例如,您将拥有

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>.

这两个堆栈跟踪在AbstractBatcher.executeBatch的第242行“满足”,然后从此以后,向上的调用跟踪与包装异常相同。


什么?原因与包装异常相同吗?我没有。。。原因应该显示出问题的根源所在,截断stacktrace时没有显示。我遇到了这个问题,想了解一下这个答案,如果有人可以改写它的话……谢谢!顺便说一句,这个答案似乎没有显示如何打印完整的堆栈跟踪。
汤姆·布里托

23
@TomBrito您将看到完整的堆栈跟踪信息-您有两个例外,一个例外另一个。如果内部(包装的)异常的堆栈跟踪为ABCDEFG,而外部异常的堆栈跟踪为ABCZ,则您将看到OuterException与堆栈跟踪ZCBA,“由” InnerException引起,而堆栈跟踪为“ GFEDC ...”然后再添加2个”。从外部堆栈跟踪来看,另外2个是A和B,为简洁起见,省略了它们。
考恩

1
这个答案是不正确的。我绝对遇到了其余几行不相同的情况。在这种情况下,解决方案是使用-XX:MaxJavaStackTraceDepth VM Option来增加堆栈跟踪的最大深度,如下文Nikita Koksharov所指出。
senfo


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

基本上在源代码中,main调用function a哪个调用function b哪个调用...哪个调用function eFunction e抛出a LowLevelException,导致函数c捕获LowLevelExceptiona并抛出a MidLevelException(将LowLevelException实例包装在实例内部MidLevelExceptionException该类具有一个构造函数,该构造函数能够接收不同的异常并将其包装)。这导致函数a捕获MidLevelException并抛出a HighLevelException,该函数现在包装了前两个Exception实例。

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

at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
at Junk.main(Junk.java:4)

但是,由于已经暗示了这三行,因此无需输出。



0

我发现这对于获取整个图片很有用。获取有关异常原因的完整堆栈跟踪(该跟踪通常显示主异常中的重复行,但可能会有所帮助)。

        ... catch( Exception e) ...

        ... catch( NoClassDefFoundError e)
        {

                for(StackTraceElement ste: e.getStackTrace())
                {
                    System.out.println(ste);
                }

                if( e.getCause()!=null )
                {
                    for(StackTraceElement ste: e.getCause().getStackTrace())
                    {
                        System.out.println(ste);
                    }
                }
        }

-2

在一篇博客文章中,我刚刚描述了如何获取不仅仅是“ BatchUpdateException:批处理失败”的方法:设置hibernate.jdbc.factory_class=org.hibernate.jdbc.NonBatchingBatcherFactory为禁用休眠中的批处理。通常,可以使用BatchUpdateException.getNextException来获取失败的原因,但是在某些情况下,这可能会返回null。然后,完全禁用批处理很有用。


这不能回答问题。它可以解决他在现实生活中的处境,因此将其添加为对他的问题的评论比发布答案可能更有帮助
Alexander Bird
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.