JAX-WS WebService via CXF provides inaccurate wsdl

979 views Asked by At

I've deployed a simple JAX-WS service, built contract-first. In the JAX-WS Endpoint configuration, I specify the location of the original wsdl. However, this is not the wsdl that is returned by cxf. The original wsdl contains policy statements that are an important part of the contract, and should be visible in the wsdl to the service consumers.

I know that the wsdl location i'm setting on the endpoint is correct. When it's not correct, deployment of the war fails. I've also logged the value to double-check.

When deployed locally, the service is available at http://localhost:8080/store-web-0.1.0/services/store.

Problem: The wsdl available at http://localhost:8080/store-web-0.1.0/services/store?wsdl does not contain the policy statements that can be seen in the original wsdl. Leaving out this important part of the contract is not acceptable.

Question: Why is the wsdl available at http://localhost:8080/store-web-0.1.0/services/store?wsdl missing the policy statements and not simply the original wsdl that is configured on the jax-ws endpoint?

Additional details are below. Please let me know if there's any other information you'd like to see.

Thanks in advance!


Details

We're using: JBoss EAP 6.2, CXF 2.7.16 (moving to CXF 3.x is not an option), Spring 4.1.6

We exclude the 'webservices' subsystem in our jboss-deployment-descriptor.xml file

JAX-WS Configuration Class

@Bean StoreImpl storeImpl() {
    return new StoreImpl();
}

@Bean
public Endpoint storeServiceEndpoint() {
    EndpointImpl endpoint = new EndpointImpl(storeImpl());
    endpoint.publish("/store");

    // This configuration is located in the WAR, but WSDL is in separate JAR
    String wsdlLocation = this.getClass().getResource("/store.wsdl").toString();

    endpoint.setWsdlLocation(wsdlLocation);
    return endpoint;
}

Web Service Implementation Class

@WebService(endpointInterface = "my.service.Store", serviceName = "store")
public class StoreImpl implements Store {

    public StoreImpl() {
    }

    @Override
    public BuySomethingResponse buySomething(BuySomethingRequest buySomethingRequest) {

        // operation implementation code here

        return response;
    }

}

Web Application Initialization

@Order(value=1)
public class StoreWebInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext container) throws ServletException {
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.register(JAXWSEndpointConfig.class);

        container.addListener(new ContextLoaderListener(context));  
    }
}

@Order(value=2)
public class CXFWebInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext container) throws ServletException {
        ServletRegistration.Dynamic dispatcher = container.addServlet("CXFServlet", CXFServlet.class);  
       dispatcher.addMapping("/services/*");
   }
}
1

There are 1 answers

0
csturtz On

I was able to find the issues, of which there were 3.

Issue #1 As seen in the JAX-WS configuration class code included in the question, I was setting the wsdl location after publishing the endpoint.

Issues #2 and #3 The @WebService annotation on the StoreImpl class needed two additional attributes set: targetNamespace and portName. Their values needed to, obviously, match what was defined in the original WSDL.