Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中无StackTrace的NullPointerException_Java_Nullpointerexception - Fatal编程技术网

Java中无StackTrace的NullPointerException

Java中无StackTrace的NullPointerException,java,nullpointerexception,Java,Nullpointerexception,我已经有Java代码实例捕获了一个NullPointerException,但是当我尝试记录StackTrace时(基本上是调用Throwable.printStackTrace()),我得到的只是: java.lang.NullPointerException 还有其他人见过这个吗?我尝试在谷歌上搜索“java空指针空堆栈跟踪”,但没有遇到类似的情况。没有提供堆栈跟踪,它只返回 对这种一次性物品的简短描述。 结果是以下各项的串联: * the name of the class of thi

我已经有Java代码实例捕获了一个
NullPointerException
,但是当我尝试记录StackTrace时(基本上是调用
Throwable.printStackTrace()
),我得到的只是:

java.lang.NullPointerException
还有其他人见过这个吗?我尝试在谷歌上搜索“java空指针空堆栈跟踪”,但没有遇到类似的情况。

没有提供堆栈跟踪,它只返回

对这种一次性物品的简短描述。 结果是以下各项的串联:

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

改为使用以输出堆栈跟踪。

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

正如您在评论中提到的,您使用的是log4j。我(无意中)发现了一个我曾经写作的地方

LOG.error(exc);
而不是典型的

LOG.error("Some informative message", e);
因为懒惰,或者只是不去想它。不幸的是,它的行为并不像你期望的那样。logger API实际上将Object作为第一个参数,而不是字符串,然后对该参数调用toString()。因此,它没有得到漂亮的堆栈跟踪,而是打印出toString——这在NPE的情况下是非常无用的


也许这就是您正在经历的情况?

另一个建议-如果您使用的是Eclipse,您可以在NullPointerException本身上设置一个断点(在调试透视图中,转到“断点”选项卡并单击其中有一个!的小图标)

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

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

以下是一些可能发生的情况的解释:

  • 正在使用的记录器/处理程序已配置为仅输出异常的消息字符串,而不是完整的堆栈跟踪

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

  • 信息来自不同的地方,与你认为的不同;e、 它实际上来自于一些第三方库方法,或者是早期调试尝试遗留下来的一些随机的东西

  • 正在记录的异常重载了一些方法以隐藏stacktrace。如果是这种情况,异常将不是真正的NullPointerException,而是NPE的某个自定义子类型,甚至是某个未连接的异常


我认为最后一种可能的解释是不太可能的,但人们至少考虑做这种事情来“防止”逆向工程。当然,它只会让诚实的开发人员的生活变得困难。

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

试着在日志中进一步查看。你可以找到罪犯


编辑:听起来很相关,但它在很久以前就被修复了,这可能不是原因。

您可能正在使用HotSpot JVM(最初由Sun Microsystems提供,后来由Oracle(OpenJDK的一部分)购买),它执行大量优化。要获取堆栈跟踪,需要将选项
-XX:-OmitStackTraceInFastThrow
传递给JVM

优化是当第一次发生异常(通常是NullPointerException)时,打印完整的堆栈跟踪,JVM记住堆栈跟踪(或者可能只是代码的位置)。当异常发生得足够频繁时,将不再打印堆栈跟踪,这样既可以获得更好的性能,也可以避免日志中充斥相同的堆栈跟踪

查看如何在HotSpot JVM中实现这一点,并搜索全局变量
OmitStackTraceInFastThrow
。上次我查看代码时(2019年),它就在文件中。

下面是一个解释:

我已经在MacOSX上测试过了

  • java版本“1.6.0_26”
  • Java(TM)SE运行时环境(build 1.6.0_26-b03-383-11A511)
  • Java HotSpot(TM)64位服务器虚拟机(构建20.1-b02-383,混合模式)

    objectstring=“abcd”;
    int i=0;
    而(i<12289){
    i++;
    试一试{
    整数a=(整数)字符串;
    }捕获(例外e){
    e、 printStackTrace();
    }
    }
    

对于这个特定的代码片段,12288次迭代(+频率?)似乎是JVM决定使用预分配异常的限制…

当您在项目中使用AspectJ时,可能会发生某些方面隐藏了其堆栈跟踪的部分。例如,今天我有:

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)

背景是什么?是否涉及多个线程?我在尝试获取SwingWorker中异常的堆栈跟踪时遇到问题。这里不涉及线程,只涉及普通的旧Java。@Bozho-不-不知道如何复制空指针。相关:有关
-XX:-在dup中忽略StackTraceInFastThrow
的详细信息:抱歉,我在我的原始帖子中说错了。我通过Log4J记录这些日志,它使用printStackTrace()。您是否尝试使用
getStackTrace()
来确保问题不在您的记录器上?如果您使用的是Log4J,请确保发送
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)