[英]JAXB - Unmarshalling custom xml throws javax.xml.bind.UnmarshalException
[英]jaxb throws javax.xml.bind.UnmarshalException: Expected elements are (none) only when running in osgi bundle
我想在我的自由 osgi Web 應用程序中使用 jaxb 解組 xml。
我有一個帶有以下代碼的捆綁包:
InputStream is = new FileInputStream(serviceXmlPath);
JAXBContext jaxbContext = JAXBContext.newInstance(Service.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
return jaxbUnmarshaller.unmarshal(is);
其中 Service 類位於同一個包中,我使用藍圖將代碼的接口作為服務公開。 然后我有另一個帶有使用它的 servlet 的包。
我對它能夠正確解組的核心代碼進行了單元測試。 但是,當我在 Osgi 包中的 webshpere Freedom 8.5.5.8 上運行它時,出現以下異常:
[err] javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"Service"). Expected elements are (none)
[err] at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:660)
我檢查以確保當我自由運行時它正在讀取正確的文件和數據,並且我的單元測試(eclipse 中的 Junit 4)和服務器都使用相同的 jre。 (在這種情況下是 IBM java 7。)我沒有隨意使用 jaxb 特性,所以它應該使用 java 中的特性。
我不明白為什么在使用 osgi 運行時代碼會失敗。 你能建議我還應該檢查什么嗎?
編輯:
我發現這是一個類加載器問題,因為我打印了類加載器並看到 JAXBContext 有一個與我自己的類不同的類加載器。 但是,使用以下代碼更改 jaxb 的類加載器:
ClassLoader classloader = MyClass.class.getClassLoader();
jaxbContext = JAXBContext.newInstance(MyClass.class.getName(), classloader);
導致:
[err] javax.xml.bind.JAXBException: Unable to create context
- with linked exception:
[java.lang.reflect.InvocationTargetException]
然后我向包中添加了一個 jaxb.index 文件,並添加了以下代碼來打印出類加載器:
JAXBContext jaxbContext = JAXBContext.newInstance(Service.class);
JAXBContext jaxbContext2 = JAXBContext.newInstance();
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
System.out.println("classloader of Service.class:" + Service.class.getClassLoader().toString());
System.out.println("classloader of JAXBContext:" + JAXBContext.class.getClassLoader());
System.out.println("classloader of jaxbContext:" + jaxbContext.getClass().getClassLoader());
System.out.println("classloader of jaxbContext2:" + jaxbContext2.getClass().getClassLoader());
System.out.println("classloader of jaxbUnmarshaller:" + Unmarshaller.class.getClassLoader());
當我運行它時,我得到了:
classloader of Service.class:org.eclipse.osgi.internal.loader.EquinoxClassLoader@b0adb798[DataService:1.0.0.qualifier(id=379)]
classloader of JAXBContext:org.eclipse.osgi.internal.loader.EquinoxClassLoader@271677de[com.ibm.ws.javaee.jaxb.2.2:1.0.11.cl50820151201-1942(id=343)]
classloader of jaxbContext:org.eclipse.osgi.internal.loader.EquinoxClassLoader@b997af78[com.ibm.ws.xlxp.1.5.3:1.0.11.cl50820151201-1942(id=341)]
classloader of jaxbContext2:org.eclipse.osgi.internal.loader.EquinoxClassLoader@b997af78[com.ibm.ws.xlxp.1.5.3:1.0.11.cl50820151201-1942(id=341)]
classloader of jaxbUnmarshaller:org.eclipse.osgi.internal.loader.EquinoxClassLoader@271677de[com.ibm.ws.javaee.jaxb.2.2:1.0.11.cl50820151201-1942(id=343)
請注意,我是否傳入類並不重要,它使用自己的類加載器(順便說一句,這是在自由啟用 jaxb2.2 的情況下。如果我禁用它,除第一個之外的類加載器都顯示為空,但是否則行為相同)
我終於讓它工作了。 在我的包清單中,我導入了包 javax.xml.bind,我認為這是我所需要的,因為這是我在調用解組的代碼中導入的內容。 事實證明,我還需要添加 javax.xml.bind.annotation,因為模型類會導入它。
無論如何,感謝斯科特的評論
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.