簡體   English   中英

jaxb 拋出 javax.xml.bind.UnmarshalException:僅在 osgi 包中運行時,預期元素為(無)

[英]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.in​​dex 文件,並添加了以下代碼來打印出類加載器:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM