Java (未知来源)异常堆栈跟踪

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3132302/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 16:43:38  来源:igfitidea点击:

(Unknown Source) in Exception stack trace

javaexceptionstack-trace

提问by polygenelubricants

Background

背景

This question is related toWhy does String.valueOf(null) throw a NullPointerException?

这个问题与为什么 String.valueOf(null) 抛出 NullPointerException 相关?

Consider the following snippet:

考虑以下片段:

public class StringValueOfNull {
    public static void main(String[] args) {
        String.valueOf(null);

        // programmer intention is to invoke valueOf(Object), but instead
        // code invokes valueOf(char[]) and throws NullPointerException
    }
}

As explained in the answer to the linked question, Java's method overloading resolves the above invokation to String.valueOf(char[]), which rightfully results in a NullPointerExceptionat run-time.

正如对链接问题的回答中所解释的那样,Java 的方法重载将上述调用解析为String.valueOf(char[]),这理所当然地NullPointerException在运行时导致。

Compiled in Eclipse and javac 1.6.0_17, this is the stack trace:

在 Eclipse 和 中编译javac 1.6.0_17,这是堆栈跟踪:

Exception in thread "main" java.lang.NullPointerException
        at java.lang.String.<init>(Unknown Source)
        at java.lang.String.valueOf(Unknown Source)
        at StringValueOfNull.main(StringValueOfNull.java:3)

Note that the stack trace above is missing the KEYinformation: it does NOThave the full signature of the valueOfmethod! It just says String.valueOf(Unknown Source)!

需要注意的是堆栈跟踪上面缺少关键信息:它具备的完整签名valueOf法!它只是说String.valueOf(Unknown Source)

In most situations I've encountered, exception stack traces always have the complete signature of the methods that are actually in the stack trace, which of course is very helpfulin identifying the problem immediately and a major reason why the stack trace (which needless to say is rather expensive to construct) is provided in the first place.

在我遇到的大多数情况下,异常堆栈跟踪始终具有实际在堆栈跟踪中的方法的完整签名,这当然有助于立即识别问题以及堆栈跟踪(无需说构建起来相当昂贵)首先提供。

And yet, in this case, the stack trace does not help at all. It has failed miserably in helping the programmer identify the problem.

然而,在这种情况下,堆栈跟踪根本没有帮助。它在帮助程序员识别问题方面失败了。

As is, I can see 3 ways that a programmer can identify the problem with the above snippet:

照原样,我可以看到程序员可以通过上述代码段识别问题的 3 种方式:

  • Programmer realizes on his/her own that the method is overloaded, and by resolution rule, the "wrong" overload gets invoked in this case
  • Programmer uses a good IDE that allows him/her to quickly see which method is selected
    • In Eclipse, for example, mouse-hovering on the above expression quickly tells programmer that the String valueOf(char[] data)is indeed the one selected
  • Programmer examines the bytecode (ugh!)
  • 程序员自己意识到该方法已重载,并且根据解析规则,在这种情况下会调用“错误”的重载
  • 程序员使用好的IDE,可以让他/她快速查看选择了哪种方法
    • 例如,在 Eclipse 中,将鼠标悬停在上述表达式上会很快告诉程序员String valueOf(char[] data)确实是被选中的
  • 程序员检查字节码(呃!)

The last option is probably the least accessible, but of course is the Ultimate Answer (a programmer may misunderstood the overloading rule, IDE may be buggy, but bytecodes always(?) tell the truth on what's being done).

最后一个选项可能是最不容易访问的,但当然是终极答案(程序员可能误解了重载规则,IDE 可能有问题,但字节码总是(?)说出正在做的事情的真相)。



The questions

问题

  • Why is the stack trace so uninformative in this case with regards to the signatures of the methods that are actually in the stack trace?
    • Is this due to the compiler? The runtime? Something else?
  • In what other (rare?) scenarios can the stack trace fail to capture essential information like these?
  • 为什么在这种情况下堆栈跟踪对于实际在堆栈跟踪中的方法的签名如此无用?
    • 这是编译器的原因吗?运行时间?还有什么?
  • 在其他哪些(罕见的?)场景中,堆栈跟踪无法捕获此类基本信息?

采纳答案by unbeli

This is normally related to missing debug information. You are probably using JRE (not JDK), which does not include debug information for rt.jar classes. Try using full JDK, you'll get proper locations in the stack trace:

这通常与缺少调试信息有关。您可能正在使用 JRE(不是 JDK),它不包括 rt.jar 类的调试信息。尝试使用完整的 JDK,您将在堆栈跟踪中获得正确的位置:

Exception in thread "main" java.lang.NullPointerException
    at java.lang.String.<init>(String.java:177)
    at java.lang.String.valueOf(String.java:2840)
    at StringValueOfNull.main(StringValueOfNull.java:3)

回答by bragboy

I ran the code in Eclipse and I got the following output,

我在 Eclipse 中运行代码,得到以下输出,

public class Aloof {
    public static void main(String[] args) {
        String.valueOf(null);
    }
}

Exception in thread "main" java.lang.NullPointerException
    at java.lang.String.<init>(String.java:177)
    at java.lang.String.valueOf(String.java:2840)
    at mysql.Aloof.main(Aloof.java:19)

If you include the full source (from JDK), you can actually debug to the line 177 in String.java

如果您包含完整的源代码(来自 JDK),您实际上可以调试到 String.java 中的第 177 行

回答by Aaron Digulla

This happens when there is no debug (line) information in the source or the VM is told to throw that information away at class loading time. Since you have some line numbers, it's not the VM setting but the class Stringis missing debug information.

当源中没有调试(行)信息或告诉 VM 在类加载时丢弃该信息时,就会发生这种情况。由于您有一些行号,这不是 VM 设置,而是该类String缺少调试信息。

回答by Supun Sameera

Note that if you are using Ant build and if the debug attribute set to false in javac command this could happen.

请注意,如果您使用 Ant 构建并且在 javac 命令中将 debug 属性设置为 false,则可能会发生这种情况。

ex : if you need proper location in trace set debug = truein Ant build,

例如:如果您需要在 Ant 构建中的跟踪集debug = true中的正确位置,

    <javac verbose="false" srcdir="${src}" destdir="${classdir}" debug="true" includes="**/*.java">
        <classpath refid="compile.classpath" />
    </javac>

回答by jamlhet

I had the same problem, I'm using springand apache antfor continuous integration.

我有同样的问题,我使用springapache ant进行持续集成。

The error I had was in the build.xml file.

我遇到的错误是在 build.xml 文件中。

The gender change log with more precise content was:

内容更精确的性别变化日志是:

build.xml with the error:

build.xml 出现错误:

    <javac srcdir="${src.home}" destdir="${work.home}/WEB-INF/classes">
        <classpath refid="compile.classpath" />
    </javac>

build.xml without error:

build.xml 没有错误:

    <javac srcdir="${src.home}" destdir="${work.home}/WEB-INF/classes"  debug="true">
        <classpath refid="compile.classpath" />
    </javac>

Within the structure I lacked the courage debug = "true"

在结构中我缺乏勇气debug = "true"

回答by Peter Tseng

In Eclipse: Preferences > Java > Installed JREs. The checked entry should have a path inside the JDK, e.g. C:\Program Files (x86)\Java\jdk1.7.0_55\jre.

在 Eclipse 中:首选项 > Java > 已安装的 JRE。选中的条目应该在 JDK 中有一个路径,例如 C:\Program Files (x86)\Java\jdk1.7.0_55\jre。