我正在尝试解组xml文件,但是从JAXB库的深处得到非常奇怪的NPE。请你帮我解决这个问题吗?
这是异常堆栈跟踪的顶部:
java.lang.NullPointerException
at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:258)
at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.handleGenericException(Loader.java:245)
at com.sun.xml.bind.v2.runtime.unmarshaller.Scope.add(Scope.java:123)
at com.sun.xml.bind.v2.runtime.property.ArrayERProperty$ReceiverImpl.receive(ArrayERProperty.java:213)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.endElement(UnmarshallingContext.java:538)
这是xml类代码:
public class Base {
public Base() {
}
}
public class A extends Base {
public A() {
}
}
public class B extends Base{
public B() {
}
}
@XmlRootElement(name = "test")
@XmlAccessorType
public class TestXml {
@XmlElementWrapper(name = "list")
@XmlAnyElement
@XmlJavaTypeAdapter(Adapter.class)
public List<Base> list = new ArrayList<>();
}
这是适配器的unmarshal()方法,它取自here并略有修改。
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public T unmarshal(Element element) throws Exception {
if (null == element) {
return null;
}
// 1. Determine the values type from the type attribute.
Class<?> clazz = classLoader.loadClass(element.getAttribute("class"));
// 2. Unmarshal the element based on the value's type.
DOMSource source = new DOMSource(element);
Unmarshaller unmarshaller = getJAXBContext(clazz).createUnmarshaller();
JAXBElement jaxbElement = unmarshaller.unmarshal(source, clazz);
return (T) jaxbElement.getValue();
}
这是测试代码:
JAXBContext jaxbContext = JAXBContext.newInstance(TestXml.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
TestXml auth = (TestXml) unmarshaller.unmarshal(new File("testData/test.xml"));
最后,这是我试图解组的xml文件:
<test>
<list>
<item class="my.package.A" />
<item class="my.package.B" />
</list>
</test>
在调试时我发现适配器工作正常,即unmarshall()方法总是返回正确类的实例,但在它之后发生了一些不好的事情。
我发现的下一件事是适配器的代码
JAXBElement jaxbElement = unmarshaller.unmarshal(source, clazz);
导致NPE。当我删除这行代码并将unmarshall()的return语句替换为
时return new A(); //for example
没有发生NPE。
答案 0 :(得分:1)
尝试更改此行,
// 1. Determine the values type from the type attribute.
Class<?> clazz = classLoader.loadClass(element.getAttribute("class"));
要,
// 1. Determine the values type from the type attribute.
Class<?> clazz = ClassLoader.loadClass(element.getAttribute("class"));
你的clazz变量的原因是null。
答案 1 :(得分:1)
在另一个解组过程中尝试处理解组过程时,我有完全相同的堆栈跟踪。
基本上,在&#39; unmarshal&#39;一个适应器的方法,我建立了一个假的标签&#39;通过剥离其价值并仅保留其属性。然后,为了正确提取属性,我使用了jaxb unmarshalling。
jaxb中的错误很深,我的代码中没有发现任何错误。我通过迁移到最新版本解决了我的问题。最好的jaxb-core库,从2.2.6到2.2.11。
答案 2 :(得分:0)
这是JDK 1.7附带的JAXB(2.2.4-2)版本中的错误。
对我来说,在类路径中包括最新版本的JAXB(2.2.11)解决了这个问题。