NullPointerException异常在Java中没有堆栈跟踪

问题描述:

我有我们的Java代码捕获一个NullPointerException的情况,但是当我尝试登录的堆栈跟踪(这基本上结束调用Throwable.printStackTrace()),我得到的是:NullPointerException异常在Java中没有堆栈跟踪

java.lang.NullPointerException 

有没有人遇到过这个?我试着用“java空指针空栈跟踪”搜索,但没有遇到类似这样的事情。

+0

什么上下文?是否涉及多个线程?我有问题试图在SwingWorker中获取异常的堆栈跟踪。 – 2010-03-09 18:26:17

+0

这里没有涉及线程,只是普通的旧Java。 – 2010-03-09 18:35:27

+0

尝试过调试器? – Bozho 2010-03-09 19:28:50

您可能正在使用执行大量优化的Sun JVM。要获取堆栈跟踪信息,您需要将选项-XX:-OmitStackTraceInFastThrow传递给JVM。

+1

感谢您的提示。任何想法,如果有任何隐藏的陷阱传递这个选项(只要我的应用程序不会抛出大量的例外,这似乎是非常无害的)? – 2010-06-11 17:48:54

+0

我知道没有隐藏的陷阱。当您查看Hotspot源代码时,可以看到该选项仅用于一个地方(graphKit.cpp)。这对我来说很好。 – 2010-06-13 11:14:19

+27

以为我会添加额外的信息,当堆栈跟踪得到优化时,这是因为它已经完全处理了至少一次:http://jawspeak.com/2010/05/26/hotspot-caused-exceptions -to全输,他们-堆栈跟踪功能于生产和的修复/ – sharakan 2012-06-19 14:56:33

exception.toString不给你的堆栈跟踪,它只返回

此throwable的简短描述。 结果的串联:

* the name of the class of this object 
* ": " (a colon and a space) 
* the result of invoking this object's getLocalizedMessage() method 

使用exception.printStackTrace而不是输出的堆栈跟踪。

+0

对不起,我在我的原帖中错过了。我通过使用printStackTrace()的Log4J来记录它们。 – 2010-03-09 18:34:19

+1

您是否尝试过使用getStackTrace()来确保问题不在您的记录器中? – 2010-03-09 18:37:54

+1

如果您使用的是log4j,请务必将异常作为参数的一部分发送到日志方法。我会发表一个答案。 – 2010-03-09 18:53:41

toString()只返回异常名称和可选消息。我建议叫

exception.printStackTrace() 

转储信息,或者如果您需要血淋淋的细节:

StackTraceElement[] trace = exception.getStackTrace() 
+0

请参阅上文 - 我错过了 - 我正在使用printStackTrace()。 – 2010-03-09 18:34:47

这将输出的异常,只能使用调试你应该处理您的异常更好。

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

正如您在评论中提到的,您使用的是log4j。我发现(非故意的),我已通过书面懒惰

LOG.error(exc); 

不是典型的

LOG.error("Some informative message", e); 

,或者也许只是不去想它的地方。这个不幸的部分是它没有像你期望的那样行事。记录器API实际上将Object作为第一个参数,而不是字符串 - 然后它在参数上调用toString()。因此,它不是获得漂亮的堆栈跟踪,而是打印出toString - 在NPE的情况下,这是非常没用的。

也许这是你正在经历的?

+0

+1:这将解释描述的行为,并且你不是唯一一个发现这个:) – 2010-03-09 18:59:47

+2

我们实际上有一个从不使用上面的第一个表单的标准策略(LOG.error(exc);) - 我们总是使用2参数签名,以便我们向日志中添加一些描述性语句,而不仅仅是一个原始堆栈跟踪。 – 2010-03-09 19:25:56

+4

当然,但政策并不意味着它总是正确执行!至少,值得一提的是它。 – 2010-03-09 20:12:27

其他建议 - 如果你使用Eclipse,您可以为自己的NullPointerException断点(!Debug透视图中,转到“断点”选项卡,然后单击具有小图标吧)

检查“已捕获”和“未被捕获”选项 - 现在,当您触发NPE时,您将立即断点,然后您可以逐步查看它的处理方式以及为什么没有获取堆栈跟踪。

(您的问题仍然不清楚您的代码是否调用printStackTrace()或者这是由日志处理程序完成的。)

这里有什么可能发生的一些可能的解释:

  • 记录器/处理器使用已被配置为只输出异常的消息字符串,而不是一个完整的堆栈跟踪。

  • 您的应用程序(或某个第三方库)使用LOG.error(ex);而不是(例如)log4j Logger方法的双参数形式记录异常。

  • 该消息来自与您认为的地方不同的地方;例如它实际上是来自一些第三方库方法,或者是一些随机的东西,它们是从早期的调试尝试中遗留下来的。

  • 正在记录的异常已重载一些方法来遮蔽堆栈跟踪。如果是这样,这个异常不会是一个真正的NullPointerException,但会是NPE的一些自定义子类型,甚至是一些未连接的异常。

我认为最后可能的解释是不太可能的,但人们至少会考虑做这种事情来“防止”逆向工程。当然,只有诚实的开发者才能真正成功。

我们在过去看到过这种相同的行为。事实证明,出于某种疯狂的原因,如果NullPointerException异常多次出现在代码中的相同位置,使用Log.error(String, Throwable)一段时间后将停止包含完整堆栈跟踪。

尝试在您的日志中寻找更远的位置。你可能会找到罪魁祸首。

编辑:this bug听起来有关,但它是很久以前修复它可能不是原因。

+1

该错误已关闭,但-XX:-OmitStackTraceInFastThrow标志仍需要解决性能优化问题。 – 2012-01-30 22:09:32

+0

我最近看到这很多。有什么线索可能会导致这种情况,或者如何解决这个问题?日志记录系统可能已经运行了好几天了,实际的原因已经过去了,从来没有想过繁琐的搜索... – 2012-12-14 08:57:14

+2

Pawel,你有没有试过Joshua建议的'-XX:-OmitStackTraceInFastThrow' JVM标志?另请参阅http://*.com/a/2070568/6198。 – 2012-12-14 23:38:59

这里有一个解释:Hotspot caused exceptions to lose their stack traces in production – and the fix

我已经测试了它在Mac OS X

  • Java版本 “1.6.0_26”
  • 的Java(TM)SE运行时环境(建1.6。 0_26-b03-383-11A511)
  • 爪哇热点(TM)64位服务器VM(构建20.1-b02-383,混合模式)

    Object string = "abcd"; 
    int i = 0; 
    while (i < 12289) { 
        i++; 
        try { 
         Integer a = (Integer) string; 
        } catch (Exception e) { 
         e.printStackTrace(); 
        } 
    } 
    

对于这个代码特异性片段,12288迭代(+频率?)好像当你在项目中使用的AspectJ是其中JVM已经决定使用预分配的除外限制...

,它可能会发生某些方面隐藏其堆栈跟踪的部分。例如,今天我有:

java.lang.NullPointerException: 
    at com.company.product.MyTest.test(MyTest.java:37) 

当通过Maven的surefire运行测试时,打印此堆栈跟踪。

在另一方面,在运行的IntelliJ测试时,一个不同的堆栈跟踪印刷:

java.lang.NullPointerException 
    at com.company.product.library.ArgumentChecker.nonNull(ArgumentChecker.java:67) 
    at ... 
    at com.company.product.aspects.CheckArgumentsAspect.wrap(CheckArgumentsAspect.java:82) 
    at ... 
    at com.company.product.MyTest.test(MyTest.java:37)