我希望我能正确地解释这一点。我正在使用Javolution库来读取和写入XML配置文件。我使用的是XMLStreamReader/Writer。在读取过程中,我希望读取标记并将其属性存储在LinkedHashMap中。然而,我抛出了一个异常,在我看来,由于它被抛出的时间和代码中当前发生的事情,它看起来没有任何意义。
使用Eclipse调试器,当一个属性的键和值被添加到我的map中时,就会抛出异常。
public class Element {
private HashMap<String, String> attributes = new LinkedHashMap<String, String>();
...
public void setAttribute(String key, String value) {
...
attributes.put(key, value);
}
}在添加了键和值之后,this立即捕获了来自Javolution的异常:
javolution.xml.stream.XMLStreamException: Local name cannot be nullkey和value都不为null。当它们被添加到映射中时,我不能进一步深入代码以查看异常被抛出的位置,没有堆栈跟踪,没有文件/行号显示在任何地方来解释异常被抛出的位置,甚至是如何抛出的。
在谷歌上快速搜索一下以前的Javolution实现,我可以看到这个特殊的异常仅仅是使用XMLStreamWriterImpl类型的几个方法抛出的。我在每次使用这些方法时都设置了断点,但是调试器直到很久以后才能在代码中捕捉到正在使用的断点(并且我的localName变量在声明时初始化)。
对于如何确定抛出此异常的原因,有人有什么建议吗?
堆栈跟踪:
Java HotSpot(TM) 64-Bit Server VM[localhost:3999]
Thread [main] (Suspended)
XMLImplMain$Element.setAttribute(String, String) line: 827
XMLImplMain.translate(Element) line: 133
XMLImplMain.translate(Element) line: 140
XMLImplMain.translate(Element) line: 140
XMLImplMain.loadXML(String) line: 118
Bootstrap.main(String[]) line: 32
Thread [EventWriter] (Running) 发布于 2013-01-15 19:39:10
当通过javac编译时,如果没有参数-g,这个Javolution库可能没有正确编译,这将使输出jar缺少调试信息。您可以找到当前正在处理的jar的对应源代码,并使用足够的参数重新编译它,使其可自行调试。
或者,还有一种解决方法,它要复杂得多,但不需要定制编译,编写一个BTrace脚本并捕获所有XMLStreamException的初始化,然后打印出堆栈跟踪,如下所示:
package com.sun.btrace.samples;
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;
@BTrace
public class OnThrow {
@OnMethod(clazz = "javolution.xml.stream.XMLStreamException", method = "<init>", location = @Location(Kind.RETURN))
public static void endMethod(@Self Exception self) {
jstack();
}
}还有一个类似的例子here。您可以更深入地挖掘here。
https://stackoverflow.com/questions/14336128
复制相似问题