我已经有我们的Java代码的实例捕捉一个NullPointerException,但当我试图记录StackTrace(基本上最终调用Throwable.printStackTrace()),我得到的是:
java.lang.NullPointerException
有人遇到过吗?我试着在谷歌上搜索“java空指针空堆栈跟踪”,但没有遇到这样的东西。
我已经有我们的Java代码的实例捕捉一个NullPointerException,但当我试图记录StackTrace(基本上最终调用Throwable.printStackTrace()),我得到的是:
java.lang.NullPointerException
有人遇到过吗?我试着在谷歌上搜索“java空指针空堆栈跟踪”,但没有遇到这样的东西。
当前回答
VM停止输出多次抛出的异常的堆栈跟踪。这是发生在C2编译中的优化之一。
根据OpenJDK源代码,此优化应用于以下例外情况:
nullpointerexception -ArithmeticException -ArrayIndexOutOfBoundsException -ArrayStoreException classcastexception
其他回答
(您的问题仍然不清楚您的代码是否调用printStackTrace()或这是由日志处理程序完成的。)
以下是一些可能的解释:
The logger / handler being used has been configured to only output the exception's message string, not a full stack trace. Your application (or some third-party library) is logging the exception using LOG.error(ex); rather than the 2-argument form of (for example) the log4j Logger method. The message is coming from somewhere different to where you think it is; e.g. it is actually coming some third-party library method, or some random stuff left over from earlier attempts to debug. The exception that is being logged has overloaded some methods to obscure the stacktrace. If that is the case, the exception won't be a genuine NullPointerException, but will be some custom subtype of NPE or even some unconnected exception.
我认为最后一种可能的解释是不太可能的,但人们至少会考虑做这种事情来“防止”逆向工程。当然,它只会让诚实的开发者的生活变得困难。
例外。toString不给你StackTrace,它只返回
这是一个简短的描述扔。 结果是: *该对象的类名 * ": "(冒号加空格) *调用该对象的getLocalizedMessage()方法的结果
使用异常。而不是printStackTrace来输出StackTrace。
您可能正在使用HotSpot JVM(最初由Sun Microsystems开发,后来被Oracle收购,是OpenJDK的一部分),它执行大量优化。为了获得堆栈跟踪,你需要将以下选项传递给JVM:
-XX:-OmitStackTraceInFastThrow
优化的方法是,当异常(通常是NullPointerException)第一次发生时,打印完整的堆栈跟踪,JVM记住堆栈跟踪(或者可能只是代码的位置)。当异常发生的次数足够频繁时,堆栈跟踪就不再打印了,这既是为了获得更好的性能,也是为了不让相同的堆栈跟踪充斥日志。
要了解这是如何在HotSpot JVM中实现的,请获取它的副本并搜索全局变量OmitStackTraceInFastThrow。我上次查看代码(在2019年)时,它位于graphKit.cpp文件中。
toString()只返回异常名称和可选消息。我建议你打电话
exception.printStackTrace()
要转储消息,或者如果你需要血腥的细节:
StackTraceElement[] trace = exception.getStackTrace()
这将输出异常,只用于调试,你应该更好地处理你的异常。
import java.io.PrintWriter;
import java.io.StringWriter;
public static String getStackTrace(Throwable t)
{
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw, true);
t.printStackTrace(pw);
pw.flush();
sw.flush();
return sw.toString();
}