CXF生成的客户端HandlerTubeFactory未实现TubeFactory

时间:2017-01-04 14:37:05

标签: java maven cxf wsdl2java cxf-client

我使用wsdl2java生成客户端。当我运行这个客户端时,我得到了

java.lang.RuntimeException: MASM0015: Class [ com.sun.xml.ws.assembler.jaxws.HandlerTubeFactory ] does not implement [ com.sun.xml.internal.ws.assembler.dev.TubeFactory ] interface
at com.sun.xml.internal.ws.assembler.TubeCreator.<init>(TubeCreator.java:63)
at com.sun.xml.internal.ws.assembler.TubelineAssemblyController.initializeTubeCreators(TubelineAssemblyController.java:116)
at com.sun.xml.internal.ws.assembler.TubelineAssemblyController.getTubeCreators(TubelineAssemblyController.java:79)
at com.sun.xml.internal.ws.assembler.MetroTubelineAssembler.createClient(MetroTubelineAssembler.java:103)
at com.sun.xml.internal.ws.client.Stub.createPipeline(Stub.java:328)
at com.sun.xml.internal.ws.client.Stub.<init>(Stub.java:295)
at com.sun.xml.internal.ws.client.Stub.<init>(Stub.java:228)
at com.sun.xml.internal.ws.client.Stub.<init>(Stub.java:243)
at com.sun.xml.internal.ws.client.sei.SEIStub.<init>(SEIStub.java:84)
at com.sun.xml.internal.ws.client.WSServiceDelegate.getStubHandler(WSServiceDelegate.java:814)
at com.sun.xml.internal.ws.client.WSServiceDelegate.createEndpointIFBaseProxy(WSServiceDelegate.java:803)
at com.sun.xml.internal.ws.client.WSServiceDelegate.getPort(WSServiceDelegate.java:436)
at com.sun.xml.internal.ws.client.WSServiceDelegate.getPort(WSServiceDelegate.java:404)
at com.sun.xml.internal.ws.client.WSServiceDelegate.getPort(WSServiceDelegate.java:386)
at javax.xml.ws.Service.getPort(Service.java:119)
at com.equifax.eid.soap.schema.ukidentityfraudservice.v1.wsdl.UkIdentityFraudService.getUkIdentityFraudServiceHttpPort(UkIdentityFraudService.java:72)

我的pom.xml包含以下相关依赖项(并未显示所有依赖项)

    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-frontend-jaxws</artifactId>
        <version>3.1.7</version>
    </dependency>
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-transports-http</artifactId>
        <version>3.1.7</version>
    </dependency>
    <dependency>
        <groupId>org.apache.wss4j</groupId>
        <artifactId>wss4j-ws-security-common</artifactId>
        <version>2.1.7</version>
    </dependency>
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-ws-security</artifactId>
        <version>3.1.7</version>
    </dependency>
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-bindings-soap</artifactId>
        <version>3.1.7</version>
    </dependency>

这是我的客户代码:

URL eapURL = UkIdentityFraudService.WSDL_LOCATION;
UkIdentityFraudService ss = new UkIdentityFraudService(eapURL, EPA_SERVICE_NAME);
epaPort = ss.getUkIdentityFraudServiceHttpPort();
Map<String, Object> epaOutProps = new HashMap<String, Object>();
Client client = org.apache.cxf.frontend.ClientProxy.getClient(epaPort);
Endpoint epaCxfEndpoint = client.getEndpoint();
epaOutProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
epaOutProps.put(WSHandlerConstants.USER, epauser);
epaOutProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_DIGEST);
epaOutProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, EpaPasswordCallback.class.getName());
WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(epaOutProps);
epaCxfEndpoint.getOutInterceptors().add(wssOut);
epaCxfEndpoint.getInInterceptors().add(new LoggingInInterceptor());
epaCxfEndpoint.getOutInterceptors().add(new LoggingOutInterceptor());

以下是生成的服务代码的顶部:

import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.WebEndpoint;
import javax.xml.ws.WebServiceClient;
import javax.xml.ws.WebServiceFeature;
import javax.xml.ws.Service;

/**
 * This class was generated by Apache CXF 3.1.7
 * 2017-01-04T10:48:02.103Z
 * Generated source version: 3.1.7
 * 
 */ 

谢谢pedrofb。我只能通过显式覆盖ServiceDelegate来实现它,将它添加到我的代码中,在一个大的try catch块中。

    Field delegateField = Service.class.getDeclaredField("delegate"); //ALLOW CXF SPECIFIC SERVICE DELEGATE ONLY!
    delegateField.setAccessible(true);
    ServiceDelegate previousDelegate = (ServiceDelegate) delegateField.get(ss);
    if (!previousDelegate.getClass().getName().contains("cxf")) {
        ServiceDelegate serviceDelegate = ((Provider) Class.forName("org.apache.cxf.jaxws.spi.ProviderImpl").newInstance())
            .createServiceDelegate(epaLoc, EPA_SERVICE_NAME, ss.getClass());
        logger.info("The " + getClass().getSimpleName() + " delegate is changed from " + "[" + previousDelegate + "] to [" +
            serviceDelegate +
            "]");
        delegateField.set(ss, serviceDelegate);
    }

1 个答案:

答案 0 :(得分:3)

错误堆栈跟踪显示客户端正在使用JRE JAX-WS内置类com.sun.xml.internal.ws.*而不是CXF类。

JVM选择JAX-WS实现扫描类路径,查找javax.xml.ws.spi.Provider。 CXF提供程序位于cxf-rt-frontend-jaxws-*.jar,因此问题的最可能原因是jar未正确部署且在类路径中不存在。

确保CXF dependencies真正部署在您的服务器中并在执行时找到