Java异常Stacktrace不打印

时间:2012-09-11 14:33:16

标签: java exception logging exception-handling log4j

我有以下代码:

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

我希望看到的输出是一个完整的堆栈跟踪,其中包含行号和失败的类的层次结构。例如,

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)

此代码正在一个更大的应用程序中运行,该应用程序也有log4j,但我希望能够将异常转换为字符串,以便我可以将其作为电子邮件发送给Java开发人员。

有没有人对如何将完整的堆栈跟踪捕获到字符串有任何想法?我不能使用Thread.currentThread()。getStackTrace(),因为这个应用程序在Java 4上运行。什么可能阻止上面的代码打印完整的堆栈跟踪?

8 个答案:

答案 0 :(得分:13)

这是因为java在服务器模式下运行时会进行一些代码优化(java -server) 跳过这个。在java args中使用-XX:-OmitStackTraceInFastThrow 请参阅以下链接了解详情:

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

答案 1 :(得分:11)

如果反复抛出异常,JVM会停止填充堆栈跟踪。我不确定为什么,但它可能是减少JVM上的负载。您需要查看较早的堆栈跟踪以查看详细信息。

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

打印

No more stack trace after 20707 thrown.

答案 2 :(得分:3)

异常可能会在catch块之前被捕获并抛出。也许在另一个你打算做逻辑的课上。

Exception一样创建的new Exception(new Throwable("java.lang.NullPointerException"));将打印出类似于您所看到的内容。

答案 3 :(得分:2)

  

有没有人对如何将完整的堆栈跟踪捕获到字符串有任何想法?

您可以使用以下方式(StringWriter.toString())将堆栈跟踪转移到String中。

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

答案 4 :(得分:1)

可能是你没有控制台输出的appender。你考虑加一个。如果没有,请将其记录为LOGGER.error(ex);使用log4j或SLF4J

答案 5 :(得分:1)

我只能想到e.printStackTrace()可能只输出字符串"java.lang.NullPointerException"的两个原因。

  • 可能在异常上调用了setStackTrace(new StackTraceElement[0])
  • 异常对象可能是一个棘手类的实例,它覆盖了printStackTrace()或其他一些方法来返回误导性信息。

答案 6 :(得分:1)

  

什么可能阻止上述代码显示完整的堆栈跟踪?

就我而言,我正在捕获的Exception的超类具有以下代码:

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

这意味着堆栈跟踪数组从未填充,所以我得到的只是:

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

没有堆栈信息,所以不知道它发生在哪里。可爱。

我能够通过捕获Exception的源代码,将其复制到我的项目中,然后删除fillInStackTrace()方法来覆盖此行为。这是骇客,但我需要该Exception的信息。

答案 7 :(得分:0)

确保您使用的是e.printStackTrace()而不是e.getStackTrace();