David
David

Reputation: 1107

Java Exception Stacktrace Not Printing

I have the following code:

import org.apache.commons.lang.exception.ExceptionUtils;
public void myMethod() {
    try {
        // do something
    } catch (Exception e) {
        System.out.println(ExceptionUtils.getStackTrace(e)); // prints "java.lang.NullPointerException"
        System.out.println(ExceptionUtils.getFullStackTrace(e)); // prints "java.lang.NullPointerException"
        e.printStackTrace(); // prints "java.lang.NullPointerException"
    }
}

The output that I would like to see is a full stacktrace with line numbers and the hierarchy of classes that failed. For example,

Exception in thread "main" java.lang.NullPointerException
        at org.Test.myMethod(Test.java:674)
        at org.TestRunner.anotherMethod(TestRunner.java:505)
        at java.util.ArrayList(ArrayList.java:405)

This code is being run inside a larger app which also has log4j, but I'm hoping to be able to get the exception into a string so I can send it as an email to the java developers.

Does anyone have any ideas about how I can capture the full stack trace to a string? I can't use Thread.currentThread().getStackTrace() since this app runs on Java 4. What might be blocking the above code from printing the full stacktrace?

Upvotes: 10

Views: 31758

Answers (8)

Gray
Gray

Reputation: 116878

What might be blocking the above code from printing the full stacktrace?

In my case, a superclass of the Exception I was catching had this code:

/* avoid the expensive and useless stack trace for API exceptions */
@Override
public Throwable fillInStackTrace() {
    return this;
}

This meant that the stack trace array was never filled in so all I got was:

org.apache.kafka.AuthException: Auth failed: Invalid username or password

with no stack information so no idea where it happens. Lovely.

I was able to override this behavior by grabbing the source for the Exception, copying it into my project, and removing the fillInStackTrace() method. It's a hack but I needed information from that Exception.

Upvotes: 1

Spider
Spider

Reputation: 1470

Make sure you used e.printStackTrace(), instead of e.getStackTrace();

Upvotes: -1

JaskeyLam
JaskeyLam

Reputation: 15755

Does anyone have any ideas about how I can capture the full stack trace to a string?

You can use the below way(StringWriter.toString()) to transfer the stack trace into a String.

 StringWriter writer = new StringWriter();
 e.printStackTrace( new PrintWriter(writer,true ));
 System. out.println("exeption stack is :\n"+writer.toString());

Upvotes: 4

2011
2011

Reputation: 421

this is beacause java does some code optimiziation when run in server mode (java -server) to skip this. use -XX:-OmitStackTraceInFastThrow in java args see link below for details:

http://jawspeak.com/2010/05/26/hotspot-caused-exceptions-to-lose-their-stack-traces-in-production-and-the-fix/

Upvotes: 18

Stephen C
Stephen C

Reputation: 718788

I can only think of 2 reasons why e.printStackTrace() might output just the string "java.lang.NullPointerException".

  • Something might have called setStackTrace(new StackTraceElement[0]) on the exception.
  • The exception object might be an instance of a tricky class that has overridden the printStackTrace() or some other method to return misleading information.

Upvotes: 1

basiljames
basiljames

Reputation: 4847

The exception might be caught and thrown somewhere before your catch block. Maybe in another class which your are calling to do the logic.

An Exception created like
new Exception(new Throwable("java.lang.NullPointerException"));
will print something like what you see.

Upvotes: 2

Peter Lawrey
Peter Lawrey

Reputation: 533500

If you repeatedly throw an exception, the JVM stop filling in the stack trace. I am not sure why but it may be to reduce load on the JVM. You need to be looking at an earlier stack trace to see the details.

for (int n = 0; ; n++) {
    try {
        Integer i = null;
        i.hashCode();
    } catch (Exception e) {
        if (e.getStackTrace().length == 0) {
            System.out.println("No more stack trace after " + n + " thrown.");
            break;
        }
    }

prints

No more stack trace after 20707 thrown.

Upvotes: 13

Chris
Chris

Reputation: 5654

May be you don't have an appender for console output. You consider adding one. If not, log it as LOGGER.error(ex); with log4j or SLF4J

Upvotes: 1

Related Questions