NullPointerException 堆栈跟踪在没有调试代理的情况下不可用
我最近发现了一个导致NullPointerException的错误。使用标准 slf4j 语句捕获并记录异常。以下为简略代码:
for(Action action : actions.getActions()) {
try {
context = action.execute(context);
} catch (Exception e) {
logger.error("...", e);
break;
}
}
如您所见,没什么好计较的。但是,在我们拥有的所有异常日志记录语句中,只有此语句不会打印堆栈跟踪。它打印的只是消息(表示为“...”)和异常类的名称(java.lang.NullPointerException)。
由于异常上的堆栈跟踪是延迟加载的,我认为可能存在某种指令重新排序问题,并决定在日志语句之前调用e.getStackTrace()。这没有任何区别。
因此,我决定在启用调试代理的情况下重新启动。但是,由于我甚至附加到该过程,因此我注意到现在堆栈跟踪正在打印。因此,显然,调试代理的存在导致一些额外的调试信息变得可用。
从那时起,我已经修复了异常的根本原因。但我想了解为什么在没有调试器的情况下堆栈跟踪不可用。有人知道吗?
说明:这不是日志记录问题。想象一下相同的 try/catch 子句,但在 catch 中,我打印了以下值:
e.getStackTrace().length
如果没有调试器,这将打印“0”,使用调试器,它将打印一个正数(在本例中为 9)。
更多信息:这发生在JDK 1.6.0_13,64bit,amd64,linux 2.6.9上