我想在我的liberty osgi web應用程序中使用jaxb解組xml。jaxb拋出javax.xml.bind.UnmarshalException:只有在osgi包中運行時,預期的元素纔是(無)元素
我有一個束中使用以下代碼:
InputStream is = new FileInputStream(serviceXmlPath);
JAXBContext jaxbContext = JAXBContext.newInstance(Service.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
return jaxbUnmarshaller.unmarshal(is);
其中服務類是在相同束中,並予使用藍圖暴露的接口的代碼作爲服務。然後我有另一個包含一個使用它的servlet的包。
我的單元測試了它能夠正確解組的核心代碼。然而,當我在一個OSGi包跑了它的Webshpere自由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)。我沒有在liberty中使用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:[email protected][DataService:1.0.0.qualifier(id=379)]
classloader of JAXBContext:[email protected][com.ibm.ws.javaee.jaxb.2.2:1.0.11.cl50820151201-1942(id=343)]
classloader of jaxbContext:[email protected][com.ibm.ws.xlxp.1.5.3:1.0.11.cl50820151201-1942(id=341)]
classloader of jaxbContext2:[email protected][com.ibm.ws.xlxp.1.5.3:1.0.11.cl50820151201-1942(id=341)]
classloader of jaxbUnmarshaller:[email protected][com.ibm.ws.javaee.jaxb.2.2:1.0.11.cl50820151201-1942(id=343)
請注意,無論我是否通過類,它都使用它自己的類加載器(順便說一下,這是在自由中啓用了jaxb2.2)並不重要。如果我禁用它的類加載器除了第一個顯示爲空,但其他行爲相同)
你打包的代碼是什麼樣的?它是否在「服務」打包的包之外? –
(更新了基於此評論的問題)在我的osgi代碼中,我有一個使用藍圖(全部在同一個包中)將接口公開爲服務的捆綁包中的'Service'類和解組代碼。然後我有第二個捆綁軟件在藍圖服務上查找來調用這個調用。 – kkcheng
我認爲如果你的解組代碼和你的JAXB類(** Service **和** Type **)在同一個bundle中,那麼對於Service.class **的引用可以按照你的想法解決至。你確定這一切都在一個捆綁? –