异常堆栈跟踪中的(未知源)

pol*_*nts 51 java exception stack-trace

背景

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

请考虑以下代码段:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

正如在链接问题的答案中所解释的那样,Java的方法重载将上面的调用解析为String.valueOf(char[]),这NullPointerException在运行时是正确的.

在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)
Run Code Online (Sandbox Code Playgroud)

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

在我遇到的大多数情况下,异常堆栈跟踪总是具有实际位于堆栈跟踪中的方法的完整签名,这当然对于立即识别问题非常有用,并且是堆栈跟踪的主要原因(不需要首先说是建造相当昂贵的.

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

按原样,我可以看到程序员可以使用以上代码段识别问题的3种方法:

  • 程序员自己意识到方法是重载的,并且通过解析规则,在这种情况下调用"错误的"重载
  • 程序员使用一个好的IDE,允许他/她快速查看选择的方法
    • 例如,在Eclipse中,鼠标悬停在上面的表达式上会很快告诉程序员String valueOf(char[] data)确实是选中的那个
  • 程序员检查字节码(呃!)

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


问题

  • 在这种情况下,为什么堆栈跟踪在实际位于堆栈跟踪中的方法的签名方面如此无法提供信息?
    • 这是由编译器引起的吗?运行时?别的什么?
  • 在其他(罕见?)场景中,堆栈跟踪无法捕获这些基本信息?

Sup*_*era 102

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

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

    <javac verbose="false" srcdir="${src}" destdir="${classdir}" debug="true" includes="**/*.java">
        <classpath refid="compile.classpath" />
    </javac>
Run Code Online (Sandbox Code Playgroud)

  • 这样做对我来说.很好的提示 (6认同)
  • +1 +1 +1,这解决了我的问题,非常感谢! (2认同)
  • 对我不起作用,添加了 debug="true" debuglevel="lines,vars,source" (2认同)

unb*_*eli 29

这通常与缺少调试信息有关.您可能正在使用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)
Run Code Online (Sandbox Code Playgroud)

  • 嗨,大家好!我知道已经有几年但是......我正在使用ant的javac,没有任何特殊的(反调试)参数,并且我的所有系统和项目路径都指向我的JDK,而不是JRE安装.还有什么可以产生"未知来源?" (8认同)

jam*_*het 6

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

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

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

build.xml包含错误:

    <javac srcdir="${src.home}" destdir="${work.home}/WEB-INF/classes">
        <classpath refid="compile.classpath" />
    </javac>
Run Code Online (Sandbox Code Playgroud)

build.xml没有错误:

    <javac srcdir="${src.home}" destdir="${work.home}/WEB-INF/classes"  debug="true">
        <classpath refid="compile.classpath" />
    </javac>
Run Code Online (Sandbox Code Playgroud)

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