我正在使用以下行来启动JAX-WS端点:
Endpoint.publish(url, impl);
我在类路径上有CXF,因此其Provider
实现由运行时通过ServiceLoader
机制获取。如果我正确理解代码,则运行时将选择Provider
返回的第一个ServiceLoader
实现。结果,CXF端点启动。
我想避免这种情况。我知道JDK附带了默认的JAX-WS实现(在我的情况下是JDK 8)。是否可以排除CXF Provider
或优先处理要优先使用的默认值? (最好不要像从CXF jar中删除服务文件定义这样的黑客程序。)
答案 0 :(得分:1)
应该可以自己找到提供者:
public static Endpoint publish(String address,
Object implementor) {
for (Provider provider : ServiceLoader.load(Provider.class)) {
if (!provider.getClass().getName().contains("cxf")) {
return provider.createAndPublishEndpoint(address, implementor);
}
}
throw new RuntimeException(
"No non-CXF JAW-WS provider found in classpath.");
}
答案 1 :(得分:0)
Endpoint.publish()
查找这样的Provider
:
Iterator
获取一个ServiceLoader
,并获取此迭代器的第一个元素Iterator
为空,请继续使用备用Provider
分辨率就我而言,迭代器中总有东西,因此Endpoint.publish()
不是一个选择。
我也尝试了@VGR建议的解决方案,但是它没有用,因为我没有Provider
可用的其他ServiceProvider
实现(默认情况下,JDK附带的实现是<可以通过ServiceProvider
使用strong>不。
我尝试使用Metro RT添加其他提供商:
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>rt</artifactId>
<version>2.3.0</version>
<scope>test</scope>
</dependency>
但是后来我遇到了另一个问题:
java.lang.ClassCastException: com.sun.org.apache.xerces.internal.dom.ElementNSImpl cannot be cast to javax.xml.soap.SOAPElement
这可能是由于Metro和旧版本的CXF都在类路径上造成的。
对我有用的方法不是很优雅:我只是直接实例化了默认的com.sun.xml.internal.ws.spi.ProviderImpl
(使用反射),并为偶然发现的变通问题添加了一些系统属性:
System.setProperty("javax.xml.bind.JAXBContext", "com.sun.xml.internal.bind.v2.ContextFactory");
Endpoint endpoint = createWSProvider().createAndPublishEndpoint(url, impl);
和
private static Provider createWSProvider() {
final String className = "com.sun.xml.internal.ws.spi.ProviderImpl";
Class<?> aClass;
try {
aClass = Class.forName(className);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
try {
return (Provider) aClass.getConstructor().newInstance();
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
com.sun.xml.internal.ws.spi.ProviderImpl
是内部实现类,而javac
会拒绝看到它。javax.xml.bind.JAXBContext
已设置为可以解决java.lang.ClassCastException: blablabla$JaxbAccessorF_bin cannot be cast to com.sun.xml.bind.v2.runtime.reflect.Accessor