LucKy_one

Always aiming higher


  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

  • 搜索

记解决引入CXF的jar包导致异常情况的过程及所学知识

发表于 2016-07-08 更新于 2016-08-18
在一个老系统中引入了CXF来实现Web Service服务端对外提供服务,却导致了系统原有的调用其他Web Service出现异常。

为了在一个已有系统中实现对外提供Web Service,并在ESB中注册,使用Apache CXF来实现提供服务的功能。在项目中引入了CXF及其依赖的JAR包并修改web.xml和spring的applicationcontext.xml(CXF和Spring集成的真好)之后,发现原有的调用其它Web Service返回的结果中文出现乱码,并且报文头出现了一些区别。逐步排查发现只要引入JAR包就会出现这个问题,于是乎开始深入研究调用Web Service调用过程来定位问题所在。

调用Web Service服务需要WSDL文件以及根据这个WSDL文件生成的jar包,jar包里除了对外暴露的接口类之外,还有一个继承javax.xml.ws.Service的类和一个包含所有可调用方法的接口类。在使用时通过Class.forName(Service的子类),并通过getConstructor(URL.class, Qname.class).newInstance(XX,XX)来实例化一个Service类,再通过getPort来获取接口的代理类,进而再调用具体的方法。

在对比分析之后,发现引入CXF包的前后,Service类中的delegate的具体实现类发生了变化。开始怀疑是因为引入的CXF的JAR包通过某种方式覆盖了默认的实现类。

最后还是借助了伟大的面向Stackoverflow编程大法:JAX-WS = When Apache CXF is installed it “steals” default JDK JAX-WS implementation

引用下大牛答案:

Apache CXF (cxf-rt-frontend-jaxws-\*.jar to be precise) registers itself as a JAX-WS provider in the JVM.
Inside the aforementioned JAR there is a file named: /META-INF/services/javax.xml.ws.spi.Provider with the following contents:
org.apache.cxf.jaxws.spi.ProviderImpl
If you now look at javax.xml.ws.spi.FactoryFinder#find method you will discover that JDK searches the CLASSPATH for the presence of javax.xml.ws.spi.Provider file and falls back to default Sun implementation if not available. So you have two options to force fallback:

  • either remove cxf-rt-frontend-jaxws-\*.jar from CLASSPATH
  • or override javax.xml.ws.spi.Provider file provided by CXF to point to fallback location

The second option is actually a bit easier. Simply create:
/src/main/resources/META-INF/services/javax.xml.ws.spi.Provider
file (assuming you are using Maven) with the following contents:
org.apache.cxf.jaxws.spi.ProviderImpl
That’s it, tested with javax.xml.ws.Endpoint#publish.


在CXF的jar包中有这么个文件/META-INF/services/javax.xml.ws.spi.Provider(文件名就是javax.xml.ws.spi.Provider),内容只有一行org.apache.cxf.jaxws.spi.ProviderImpl。
这个时候就涉及到了JAVA SPI(Service Provider Interface)技术,简单来说就是通过配置文件来动态指定实现类。
这篇博客写的非常浅显易懂:Java SPI机制简介

在删除了CXF的JAR包中的javax.xml.ws.spi.Provider文件之后就一切恢复了正常,但是这并没有很好的解决问题,删除之后使用默认的Provider对CXF的功能有什么影响还有待测试,但起码定位了问题,后续继续研究学习!

# JAVA # Web Service # CXF # SPI(Service Provider Interface)
加权随机算法
Apache CXF部署到WebSphere Application Server
  • 文章目录
  • 站点概览

Liu Tianhe

喜欢金融,喜欢科技
31 日志
29 标签
RSS
GitHub E-Mail
  1. 1. 引用下大牛答案:
© 2014 – 2022 Liu Tianhe
由 Hexo 强力驱动 v3.9.0
|
主题 – NexT.Mist v7.3.0