(未知源)在exception堆栈跟踪
背景
这个问题与 为什么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 } }
正如链接问题的答案中所解释的,Java的方法重载将上述调用parsing为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)
请注意,上面的堆栈跟踪缺lessKEY信息:它没有valueOf
方法的完整签名! 它只是说String.valueOf(Unknown Source)
!
在我遇到的大多数情况下,exception堆栈跟踪总是有实际上在堆栈跟踪中的方法的完整签名,这当然对于立即识别问题是非常有帮助的 ,这也是堆栈跟踪(其中不必要说是相当昂贵的build设)是提供在第一位。
然而,在这种情况下,堆栈跟踪根本没有任何帮助 。 它在帮助程序员识别问题上失败了。
正如我所看到的,程序员可以通过上面的代码来找出3种方法:
- 程序员自己意识到方法是超载的,通过parsing规则,在这种情况下调用“错误的”过载
- 程序员使用一个好的IDE,让他/她快速看到select哪种方法
- 例如,在Eclipse中,鼠标hover在上面的expression式上,很快告诉程序员,
String valueOf(char[] data)
确实是选中的一个
- 例如,在Eclipse中,鼠标hover在上面的expression式上,很快告诉程序员,
- 程序员检查字节码(呃!)
最后一个选项可能是最不容易访问的,但是当然是终极答案(程序员可能误解了重载规则,IDE可能是错误的,但是字节码总是(?)说明正在做什么)。
问题
- 为什么在这种情况下堆栈跟踪在实际上在堆栈跟踪中的方法的签名方面是如此无用?
- 这是由于编译器? 运行时? 别的东西?
- 在其他(罕见的)情况下,堆栈跟踪可能无法捕获像这样的重要信息?
这通常与缺lessdebugging信息有关。 您可能正在使用JRE(而不是JDK),它不包含rt.jar类的debugging信息。 尝试使用完整的JDK,您将在堆栈跟踪中find正确的位置:
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)
请注意,如果您正在使用Ant构build,并且在javac命令中将debug属性设置为false,则可能会发生这种情况。
例如:如果你需要跟踪设置正确的位置在Ant构builddebug = true ,
<javac verbose="false" srcdir="${src}" destdir="${classdir}" debug="true" includes="**/*.java"> <classpath refid="compile.classpath" /> </javac>
我有同样的问题,我正在使用spring和Apache的ant进行持续集成。
我有错误是在build.xml文件。
更精确的内容的性别变化日志是:
与错误的build.xml:
<javac srcdir="${src.home}" destdir="${work.home}/WEB-INF/classes"> <classpath refid="compile.classpath" /> </javac>
build.xml没有错误:
<javac srcdir="${src.home}" destdir="${work.home}/WEB-INF/classes" debug="true"> <classpath refid="compile.classpath" /> </javac>
在结构中我缺乏勇气debug =“true”
我在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)
如果您包含完整的源代码(来自JDK),则实际上可以在String.java中debugging到第177行
当源代码中没有debugging(行)信息时,会发生这种情况,或者在类加载时告诉VM将这些信息扔掉。 由于你有一些行号,这不是虚拟机的设置,但类String
缺lessdebugging信息。
在Eclipse中:首选项> Java>已安装的JRE。 检查的条目应该在JDK中有一个path,例如C:\ Program Files(x86)\ Java \ jdk1.7.0_55 \ jre。