我有一个部署在WebSphere 9.0.5.2上的应用程序,我想在其中使用CXF进行Web服务调用,并且收到此This ServiceConfigurationError
WrapperedException { java.util.ServiceConfigurationError: javax.xml.ws.spi.Provider: Provider org.apache.cxf.jaxws.spi.ProviderImpl could not be instantiated
进一步向下的堆栈跟踪,我看到这是由LinkageError引起的
Caused by: java.lang.LinkageError: loading constraint violation when overriding method
"javax/xml/ws/spi/ServiceDelegate.createDispatch(Ljavax/xml/namespace/QName;Ljavax/xml/bind/JAXBContext;Ljavax/xml/ws/Service$Mode;)Ljavax/xml/ws/Dispatch;" during creation of class
"org/apache/cxf/jaxws/ServiceImpl": loader
"com/ibm/ws/classloader/CompoundClassLoader@832133d2" of class
"org/apache/cxf/jaxws/ServiceImpl" and loader
"com/ibm/oti/vm/BootstrapClassLoader@2eec706a" of class
"javax/xml/ws/spi/ServiceDelegate" have different types for the method signature
[我知道这可能是由于多个库为QName
或JAXBContext
定义了不同,但是我认为我已经排除了这些库。
[我也知道WebSphere拥有自己的JAX-WS,并且具有ServiceDelegate.createDispatch的方法签名,并且我已经按照此处的说明尝试在WebSphere中将DisableIBMJAXWSEngine
设置为true
Using a third-party JAX-WS web services engine
我仍然无法摆脱错误,并且对下一步尝试感到茫然。任何建议表示赞赏!
这里的问题是应用程序和服务器的JAXB API,JAX-WS API和JAX-WS实现的副本之间的交叉链接。该应用程序(配置有后代父类加载委托,因此在委派给父级之前在本地进行搜索)包含JAX-WS实现和JAXB API / impl,但不包含JAX-WS API。由于JAX-WS引用了JAXB,因此获得以下链接模式:
1)某些应用程序类引用了JAX-WS API。因为它没有打包在应用程序中,所以是从服务器库中加载的。
2)链接API类时,它使用其本地类加载器查找JAXB API。依次将其也链接到服务器的版本。
3)JAX-WS使用线程上下文类加载器加载其实现。它在最后一个父应用程序中找到它。
4)链接实现类时,它使用其本地类加载器查找JAXB API,该JAXB API在应用程序中本地找到。
5)现在,实现链接到同一类的两个版本:
JAXWSImpl-> JAXWSAPI-> JAXB(服务器)JAXWSImpl-> JAXB(应用程序)
JVM无法忍受,并且抛出了LinkageError。
可以通过以下两种方法之一来解决问题:
1)将JAX-WS API添加到应用程序-这样可以防止在上面的#1中进行初始委派
2)从应用程序中删除JAXB API(和实现,如果提供的话-这会导致#4中的链接向下委托给JAXB服务器,因此它总是从同一位置加载。
无论哪种方法,技巧都是通过同一类加载器确保所有必需的类对应用程序可用。