Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to force java to show full stack trace

I'm trying to debug issue with an app that throws exception, and the stack trace is cut off even when I use -XX:MaxJavaStackTraceDepth=16777216 (or any other value there, like -1 or 2048).

It is cut off like this:

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

I want to see more stack trace elements instead of ... 89 more how to achieve that?

This is in Java 8 using SLF4J + Logback for logging with the following configuration:

<?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>
like image 826
Krzysztof Krasoń Avatar asked May 12 '20 12:05

Krzysztof Krasoń


People also ask

How can I get the current stack trace in Java?

You can use Thread. currentThread(). getStackTrace() . That returns an array of StackTraceElement s that represent the current stack trace of a program.

How do I print a whole stack trace?

Using printStackTrace() method − It print the name of the exception, description and complete stack trace including the line where exception occurred. Using toString() method − It prints the name and description of the exception. Using getMessage() method − Mostly used. It prints the description of the exception.

How do I get stack trace?

You can obtain a stack trace from a thread – by calling the getStackTrace method on that Thread instance. This invocation returns an array of StackTraceElement, from which details about stack frames of the thread can be extracted.

How can I print stack trace without exception?

Just use new Throwable(). printStackTrace() method and it will print complete stack trace from where a method is called, into the console.


1 Answers

When you have an example program like this:

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");
    }
}

It will produce:

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

Since within bar, the method invocation that led to an exception is on a different line than the construction of the wrapping secondary exception, it appears in both stack traces. The call chain of bar, i.e. main > foo, is identical and hence, omitted in the cause.

The stack trace still is recorded in the throwable, only the printing is affected. That’s why JVM options regarding the recording do not affect this. E.g.

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");
    }
}

will print

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)
like image 123
Holger Avatar answered Oct 22 '22 11:10

Holger