同一项目下两个webservice冲突的问题
程序员文章站
2022-07-13 12:18:40
...
同一项目下两个webservice冲突的问题
首先看下javax.xml.ws.spi.Provider的API:
public static Provider provider()
创建一个新的提供者对象。
用于查找将要使用的提供者子类的算法由以下几个步骤组成:
• 如果存在名为 META-INF/services/javax.xml.ws.spi.Provider 的资源,则它的第一行(如果存在)被用作实现类的 UTF-8 编码名称。
• 如果存在 $java.home/lib/jaxws.properties 文件,可以通过 java.util.Properties.load(InputStream) 方法读取它,并且该文件包含键为 javax.xml.ws.spi.Provider 的条目,则该条目的值被用作实现类的名称。
• 如果定义了名为 javax.xml.ws.spi.Provider 的系统属性,则它的值被用作实现类的名称。
• 最后,使用默认的实现类名称。
从中可以看出,比如一项目下有JBoss webservice和CXF,就会出现冲突,如何让这两个共存呢?比如我的项目是个老项目,里面是JBoss webservice,我不肯能删除它的jar包,但又要用CXF,怎么办?
下面列出我的实践步骤(可能会有更好的方法):
1. 创建一个XXXProvider extends Provider
2. 将CXF的lib/endorsed目录打开,反编译geronimo-jaxws_2.2_spec-1.1.jar(有源码更好),将CXF重写的Provider类内容copy到XXXProvider
3. 注掉public abstract ServiceDelegate createServiceDelegate(URL paramURL, QName paramQName, Class<? extends Service> paramClass);
4. Copy java的FactoryFinder类到XXXProvider下,修改find方法下的serviceId,
String serviceId = "META-INF/services/" + factoryId;,可以改成区别于这个目录的,不改仍会冲突,我的就直接改成String serviceId = factoryId;
5. 打开 cxf-2.5.2.jar copy META-INF/services/目录下的javax.xml.ws.spi.Provider文件放到src下
6. 将通过CXF生成的客户端文件Service 文件,比如我的ContentService.java,修改其构造方法,如下:
7. 项目下需要的jar包:cxf-2.5.2.jar,geronimo-jaxws_2.2_spec-1.1.jar,neethi-3.0.1.jar,wsdl4j-1.6.2.jar,xmlschema-core-2.0.1.jar
贴上这个blog其实就是把自己经历的记录下来,以后碰到的话可做个参考,大家有什么好的方法,可以贴上来,一起学习下,或者我的方法有什么问题,大家也请指教。
首先看下javax.xml.ws.spi.Provider的API:
public static Provider provider()
创建一个新的提供者对象。
用于查找将要使用的提供者子类的算法由以下几个步骤组成:
• 如果存在名为 META-INF/services/javax.xml.ws.spi.Provider 的资源,则它的第一行(如果存在)被用作实现类的 UTF-8 编码名称。
• 如果存在 $java.home/lib/jaxws.properties 文件,可以通过 java.util.Properties.load(InputStream) 方法读取它,并且该文件包含键为 javax.xml.ws.spi.Provider 的条目,则该条目的值被用作实现类的名称。
• 如果定义了名为 javax.xml.ws.spi.Provider 的系统属性,则它的值被用作实现类的名称。
• 最后,使用默认的实现类名称。
从中可以看出,比如一项目下有JBoss webservice和CXF,就会出现冲突,如何让这两个共存呢?比如我的项目是个老项目,里面是JBoss webservice,我不肯能删除它的jar包,但又要用CXF,怎么办?
下面列出我的实践步骤(可能会有更好的方法):
1. 创建一个XXXProvider extends Provider
2. 将CXF的lib/endorsed目录打开,反编译geronimo-jaxws_2.2_spec-1.1.jar(有源码更好),将CXF重写的Provider类内容copy到XXXProvider
3. 注掉public abstract ServiceDelegate createServiceDelegate(URL paramURL, QName paramQName, Class<? extends Service> paramClass);
4. Copy java的FactoryFinder类到XXXProvider下,修改find方法下的serviceId,
String serviceId = "META-INF/services/" + factoryId;,可以改成区别于这个目录的,不改仍会冲突,我的就直接改成String serviceId = factoryId;
5. 打开 cxf-2.5.2.jar copy META-INF/services/目录下的javax.xml.ws.spi.Provider文件放到src下
6. 将通过CXF生成的客户端文件Service 文件,比如我的ContentService.java,修改其构造方法,如下:
public ContentService(URL wsdlLocation, QName serviceName) throws Exception { super(wsdlLocation, serviceName); //下面是修改的,通过反射 ServiceDelegate delegate = FTVPProvider.provider().createServiceDelegate(wsdlLocation, serviceName, this.getClass()); Field field = this.getClass().getSuperclass().getDeclaredField("delegate"); field.setAccessible(true); field.set(this, delegate); }
7. 项目下需要的jar包:cxf-2.5.2.jar,geronimo-jaxws_2.2_spec-1.1.jar,neethi-3.0.1.jar,wsdl4j-1.6.2.jar,xmlschema-core-2.0.1.jar
贴上这个blog其实就是把自己经历的记录下来,以后碰到的话可做个参考,大家有什么好的方法,可以贴上来,一起学习下,或者我的方法有什么问题,大家也请指教。