我正在研究一个已经实现了基于metro
的web服务客户端的项目。现在,我需要为不同的服务添加另一个客户端。我实现了新的客户端,但现在它抛出异常时,有头(头是必需的)。如果我删除所有的metro jar,这个新客户端可以正常工作,但显然我的metro客户端失败了。我需要在可能的选择、变通方法或解决方案方面的指导。
Caused by: javax.xml.ws.WebServiceException: java.lang.ClassCastException: com.sun.xml.ws.message.saaj.SAAJHeader cannot be cast to com.sun.xml.ws.security.opt.impl.outgoing.SecurityHeader
at com.sun.xml.wss.jaxws.impl.SecurityClientTube.processRequest(SecurityClientTube.java:250)
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:961)
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:910)
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:873)
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:775)
at com.sun.xml.ws.client.Stub.process(Stub.java:429)
at com.sun.xml.ws.client.sei.SEIStub.doProcess(SEIStub.java:168)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:119)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:102)
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:151)
at com.sun.proxy.$Proxy70.methodName(Unknown Source)
... 15 more
Caused by: java.lang.ClassCastException: com.sun.xml.ws.message.saaj.SAAJHeader cannot be cast to com.sun.xml.ws.security.opt.impl.outgoing.SecurityHeader
at com.sun.xml.ws.security.opt.impl.JAXBFilterProcessingContext.setJAXWSMessage(JAXBFilterProcessingContext.java:166)
at com.sun.xml.wss.jaxws.impl.SecurityTubeBase.secureOutboundMessage(SecurityTubeBase.java:381)
at com.sun.xml.wss.jaxws.impl.SecurityClientTube.processClientRequestPacket(SecurityClientTube.java:323)
at com.sun.xml.wss.jaxws.impl.SecurityClientTube.processRequest(SecurityClientTube.java:247)
我发现一些问题与类似的问题像这里,但他们最终都建议删除头,这不是我的选择。
p。S:对于现有的使用metro jar的webservice客户端,我们使用服务器方提供的类似client的连接器(它实际上包含了所有metro相关的类)来连接到他们的服务器(我认为这很奇怪)。如果我从连接器上移开任何东西,支持协议就无效了。所以我不喜欢移除地铁罐子,而是找到另一种方式来容纳它。
很明显,第三方jar中的metro库版本与您尝试使用的新metro库版本存在冲突。
我的第一个想法是,你能控制类路径的顺序吗?您是否可以将自己的metro jar放到类路径的任意一端,看看这是否有区别?
那么也许最好尝试实现你自己的接口,根据包含在第三方库中的metro库?我不确定您是否可以获得这种版本信息,但是大多数现代IDE应该能够为您反编译第三方jar中的类。如果我在你的情况下,这将是我尝试的第一件事,因为它有"最少的移动部件",并使用你已经可用的依赖项。另一种选择是在单独的VM中运行一个或其他客户端,并通过基本的RMI接口进行访问。我知道这不理想。
您也可以尝试研究Maven阴影插件,它支持重新打包库,以便它们不会与其他版本冲突,尽管我不确定它与预编译二进制文件的工作效果如何-特别是JAX-WS包所涉及的那种复杂性…