JAX-WS Provider (JAXB) 的加載順序

問題

項目中使用JAX-WS 2.1.4,拋出以下錯誤

 

Caused by: java.lang.ClassCastException: com.sun.xml.bind.v2.runtime.JAXBContextImpl cannot be cast to com.sun.xml.internal.bind.api.JAXBRIContext
      at com.sun.xml.internal.ws.fault.SOAPFaultBuilder.<clinit>(SOAPFaultBuilder.java:533)
環境
- JAX-WS 2.1.4
- JDK 1.6.0.22
maven depedency declaration 
 
條件
當server端的web service 拋出異常時,比如NEP,客戶端拋出上面的ClassCastException
背景
爲什麼不使用JDK自帶的jax-ws?
因爲我們需要將sevice deploy在tomcat中,要用到com.sun.xml.ws.transport.http.servlet.WSServletContextListener。
而com.sun.xml.ws.transport.http.servlet.* 是J2ee的一部分,並沒有發佈在JDK中。

起因

JAX-WS provider is loaded from JDK rt.jar com.sun.xml.internal.ws.spi.ProviderImpl,使用com.sun.xml.internal.bind.v2.* 中的class

while JAXB Context is load from Jaxb-impl-2.1.7.jar com.sun.xml.bind.v2.ContextFactory,不是JDK自帶的JAXB

源頭

出現上面原因,一種可能性是應用程序的lib中加入了jaxb-impl.jar,而沒有引入jaxws-rt的jar
而我們的應用已經引入了jaxws-rt(如前maven declaration)和jaxb-impl.jar,理論上都是從應用程序的依賴包中加載纔對。
在靈光一現之後,發現src folder有人放了下面文件,指定JAXB爲JDK的實現
|_META-INF
|_services
|_ javax.xml.ws.spi.Provider (com.sun.xml.internal.ws.spi.ProviderImpl)

解決

reomve 掉上面的META-INF folder 即可

總結

JDK中的很多API採用了service provider interface (SPI)的機制,(XML, encryption)
JDK定義上層的contract/API,並提供默認的實現,應用本身可根據需要提供自己的實現。
一般由Provider類加載不同的實現。
JAX-WS 的加載順序
javax.xml.ws.spi.Provider provider()
  • If a resource with the name of META-INF/services/javax.xml.ws.spi.Provider
    = com.sun.xml.ws.spi.ProviderImpl
  • $java.home/lib/jaxws.properties,it contains an entry whose key is javax.xml.ws.spi.Provider
  • If a system property with the name javax.xml.ws.spi.Provider
  • Default is loaded(com.sun.xml.internal.ws.spi.ProviderImpl)
javax.xml.bind.ContextFinder.find
  • jaxb.properties (key=javax.xml.bind.JAXBContext)
  • System property with name javax.xml.bind.JAXBContext
  • META-INF/services/javax.xml.bind.JAXBContext 
  • Default is loaded(com.sun.xml.internal.bind.v2.ContextFactory)
|_META-INF
|_services
|_ javax.xml.bind.JAXBContext (com.sun.xml.bind.v2.ContextFactory)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章