7

我有以下代码:

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 上运行。什么可能阻止上述代码打印完整的堆栈跟踪?

4

8 回答 8

17

这是因为 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/

于 2013-03-08T13:50:45.240 回答
13

如果您反复抛出异常,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.
于 2012-09-11T14:55:20.860 回答
3

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

您可以使用以下方式(StringWriter.toString())将堆栈跟踪转换为字符串。

 StringWriter writer = new StringWriter();
 e.printStackTrace( new PrintWriter(writer,true ));
 System. out.println("exeption stack is :\n"+writer.toString());
于 2014-08-07T05:14:50.490 回答
2

异常可能会在您的 catch 块之前被捕获并抛出。也许在您要求执行逻辑的另一个类中。

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

于 2012-09-11T14:55:58.650 回答
1

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

于 2012-09-11T14:46:11.050 回答
1

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

  • 某些东西可能调用setStackTrace(new StackTraceElement[0])了异常。
  • 异常对象可能是一个棘手的类的实例,它覆盖了printStackTrace()或其他一些方法以返回误导性信息。
于 2012-09-11T15:06:03.180 回答
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

于 2019-10-15T22:12:31.233 回答
0

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

于 2019-02-24T22:14:24.350 回答