如何强制 java 显示完整的堆栈跟踪
How to force java to show full stack trace
我正在尝试调试抛出异常的应用程序问题,即使我使用 -XX:MaxJavaStackTraceDepth=16777216
(或那里的任何其他值,如 -1
或 2048
).
是这样截断的:
Caused by: java.lang.IllegalStateException: unexpected message type: DefaultLastHttpContent
at io.netty.handler.codec.http.HttpObjectEncoder.encode(HttpObjectEncoder.java:124)
at io.netty.handler.codec.http.HttpClientCodec$Encoder.encode(HttpClientCodec.java:167)
at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:89)
... 89 more
我想查看更多堆栈跟踪元素而不是 ... 89 more
如何实现?
这是在 Java 8 中使用 SLF4J + Logback 使用以下配置进行日志记录:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
</Pattern>
</layout>
</appender>
<root level="info">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
当你有这样的示例程序时:
public class ExceptionExample {
public static void main(String[] args) {
foo();
}
static void foo() {
bar();
}
static void bar() {
try { baz(); }
catch(Exception ex) { throw new RuntimeException("secondary", ex); }
}
static void baz() {
throw new RuntimeException("primary");
}
}
它将产生:
Exception in thread "main" java.lang.RuntimeException: secondary
at ExceptionExample.bar(ExceptionExample.java:11)
at ExceptionExample.foo(ExceptionExample.java:7)
at ExceptionExample.main(ExceptionExample.java:4)
Caused by: java.lang.RuntimeException: primary
at ExceptionExample.baz(ExceptionExample.java:14)
at ExceptionExample.bar(ExceptionExample.java:10)
... 2 more
由于在 bar
中,导致异常的方法调用与包装辅助异常的构造位于不同的行,因此它出现在两个堆栈跟踪中。 bar
的调用链,即 main
> foo
,是相同的,因此在原因中被省略。
堆栈跟踪仍然记录在throwable中,只有打印受到影响。这就是有关记录的 JVM 选项不会影响这一点的原因。例如
public class ExceptionExample {
public static void main(String[] args) {
try {
foo();
}
catch(Throwable t) {
for(; t != null; t = t.getCause()) {
System.err.println(t);
for(StackTraceElement e: t.getStackTrace())
System.err.println("\tat "+e);
}
}
}
static void foo() {
bar();
}
static void bar() {
try { baz(); }
catch(Exception ex) { throw new RuntimeException("secondary", ex); }
}
static void baz() {
throw new RuntimeException("primary");
}
}
将打印
java.lang.RuntimeException: secondary
at ExceptionExample.bar(ExceptionExample.java:20)
at ExceptionExample.foo(ExceptionExample.java:16)
at ExceptionExample.main(ExceptionExample.java:5)
java.lang.RuntimeException: primary
at ExceptionExample.baz(ExceptionExample.java:23)
at ExceptionExample.bar(ExceptionExample.java:19)
at ExceptionExample.foo(ExceptionExample.java:16)
at ExceptionExample.main(ExceptionExample.java:5)
我正在尝试调试抛出异常的应用程序问题,即使我使用 -XX:MaxJavaStackTraceDepth=16777216
(或那里的任何其他值,如 -1
或 2048
).
是这样截断的:
Caused by: java.lang.IllegalStateException: unexpected message type: DefaultLastHttpContent
at io.netty.handler.codec.http.HttpObjectEncoder.encode(HttpObjectEncoder.java:124)
at io.netty.handler.codec.http.HttpClientCodec$Encoder.encode(HttpClientCodec.java:167)
at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:89)
... 89 more
我想查看更多堆栈跟踪元素而不是 ... 89 more
如何实现?
这是在 Java 8 中使用 SLF4J + Logback 使用以下配置进行日志记录:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
</Pattern>
</layout>
</appender>
<root level="info">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
当你有这样的示例程序时:
public class ExceptionExample {
public static void main(String[] args) {
foo();
}
static void foo() {
bar();
}
static void bar() {
try { baz(); }
catch(Exception ex) { throw new RuntimeException("secondary", ex); }
}
static void baz() {
throw new RuntimeException("primary");
}
}
它将产生:
Exception in thread "main" java.lang.RuntimeException: secondary
at ExceptionExample.bar(ExceptionExample.java:11)
at ExceptionExample.foo(ExceptionExample.java:7)
at ExceptionExample.main(ExceptionExample.java:4)
Caused by: java.lang.RuntimeException: primary
at ExceptionExample.baz(ExceptionExample.java:14)
at ExceptionExample.bar(ExceptionExample.java:10)
... 2 more
由于在 bar
中,导致异常的方法调用与包装辅助异常的构造位于不同的行,因此它出现在两个堆栈跟踪中。 bar
的调用链,即 main
> foo
,是相同的,因此在原因中被省略。
堆栈跟踪仍然记录在throwable中,只有打印受到影响。这就是有关记录的 JVM 选项不会影响这一点的原因。例如
public class ExceptionExample {
public static void main(String[] args) {
try {
foo();
}
catch(Throwable t) {
for(; t != null; t = t.getCause()) {
System.err.println(t);
for(StackTraceElement e: t.getStackTrace())
System.err.println("\tat "+e);
}
}
}
static void foo() {
bar();
}
static void bar() {
try { baz(); }
catch(Exception ex) { throw new RuntimeException("secondary", ex); }
}
static void baz() {
throw new RuntimeException("primary");
}
}
将打印
java.lang.RuntimeException: secondary
at ExceptionExample.bar(ExceptionExample.java:20)
at ExceptionExample.foo(ExceptionExample.java:16)
at ExceptionExample.main(ExceptionExample.java:5)
java.lang.RuntimeException: primary
at ExceptionExample.baz(ExceptionExample.java:23)
at ExceptionExample.bar(ExceptionExample.java:19)
at ExceptionExample.foo(ExceptionExample.java:16)
at ExceptionExample.main(ExceptionExample.java:5)