我正在尝试解码 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。
最佳答案
尝试更改此行,
// 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 变量的原因为空。
关于java - Unmarshal NullPointerException(使用 JAXB 引用实现),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22226048/