2016-04-16 80 views
1

我想在我的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.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:[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)並不重要。如果我禁用它的類加載器除了第一個顯示爲空,但其他行爲相同)

+0

你打包的代碼是什麼樣的?它是否在「服務」打包的包之外? –

+0

(更新了基於此評論的問題)在我的osgi代碼中,我有一個使用藍圖(全部在同一個包中)將接口公開爲服務的捆綁包中的'Service'類和解組代碼。然後我有第二個捆綁軟件在藍圖服務上查找來調用這個調用。 – kkcheng

+0

我認爲如果你的解組代碼和你的JAXB類(** Service **和** Type **)在同一個bundle中,那麼對於Service.class **的引用可以按照你的想法解決至。你確定這一切都在一個捆綁? –

回答

1

我終於得到它的工作。在我的包清單中,我導入了包javax.xml.bind,我認爲這是我所需要的,因爲這是我在調用解組的代碼中導入的。事實證明,我還需要添加javax.xml.bind.annotation,因爲模型類會導入它。

無論如何,感謝Scott的意見

相關問題