soap-clientwebservices-clientjboss-eap-7

Jboss EAP 7 Webservice issue "Could not unwrap Operation", Incorrect SOAP request is generated


I am migrating our Jboss 5 webservices to Jboss EAP 7. While invoking the service, we are seeing issues where the generated SOAP request has merged two tags resulting in Error response.

First I see a warning: Could not unwrap operation

09:53:10,936 INFO [org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean] (default task-24) Creating Service {Crmr5100}Crmr5100 from WSDL: http://intwsdev.internal.myservices:8080/crm/services/Crmr5100?wsdl
09:53:11,069 WARNING [org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean] (default task-24) Could not unwrap Operation {Crmr5100}Crmr5100AdditionalIdDetail to match method "public abstract void webservices.stubs.crmr5100.Crmr5100Port.crmr5100AdditionalIdDetail(webservices.stubs.crmr5100.Crmr5100AdditionalIdDetail$Request,javax.xml.ws.Holder,javax.xml.ws.Holder)"

I understand that the warning says that the method is not matching, but I don't think it is true, below is my generated port interface

/** 
  * This class was generated by the JAX-WS RI. 
  * JAX-WS RI 2.1.3.2-02/08/2010 05:22 PM(mockbuild)-SNAPSHOT 
  * Generated source version: 2.0 
  */  
 @WebService(name = "Crmr5100Port", targetNamespace = "Crmr5100")  
 public interface Crmr5100Port {  

     /** 
      *  
      * @param response 
      * @param error 
      * @param request 
      */  
     @WebMethod(operationName = "Crmr5100AdditionalIdDetail", action = "Crmr5100")  
     @RequestWrapper(localName = "Crmr5100AdditionalIdDetail", targetNamespace = "Crmr5100", className = "webservices.stubs.crmr5100.Crmr5100AdditionalIdDetail")  
     @ResponseWrapper(localName = "Crmr5100AdditionalIdDetailResponse", targetNamespace = "Crmr5100", className = "webservices.stubs.crmr5100.Crmr5100AdditionalIdDetailResponse")  
     public void crmr5100AdditionalIdDetail(  
         @WebParam(name = "request", targetNamespace = "")  
         webservices.stubs.crmr5100.Crmr5100AdditionalIdDetail.Request request,

         @WebParam(name = "response", targetNamespace = "", mode = WebParam.Mode.OUT)  
         Holder<webservices.stubs.crmr5100.Crmr5100AdditionalIdDetailResponse.Response> response,  
         @WebParam(name = "error", targetNamespace = "", mode = WebParam.Mode.OUT)  
         Holder<webservices.stubs.crmr5100.Crmr5100AdditionalIdDetailResponse.Error> error);  
 }

And this is how I am calling the service, the wsInterfaceFactory.getPort() just calls javax.xml.ws.Service(URL url, new QName(namespace, serviceName) and getPort(new QName(nameSpace, portName), portClass)

                Crmr5100Port ws = wsInterfaceFactory.getPort(Crmr5100Port.class);  
                Crmr5100AdditionalIdDetail.Request request = new Crmr5100AdditionalIdDetail.Request();  
                request.setCommand("OPEN");  
                request.setClientId(credentials.getUsername());  
                request.setClientPassword(credentials.getWebServicePassword());  
                request.setComCfg(systemOptions.getOptionValueAsString("COMCFG"));  
                Crmr5100AdditionalIdDetail.Request.ImportImap1AdditionalId importAddn = new Crmr5100AdditionalIdDetail.Request.ImportImap1AdditionalId();  
                importAddn.setId(BigInteger.valueOf(a_additionalId));  
                importAddn.setAdditionalId(a_aiNumber);  
                request.setImportImap1AdditionalId(importAddn);  
                Holder<webservices.stubs.crmr5100.Crmr5100AdditionalIdDetailResponse.Response> response = new Holder<>();  
                Holder<webservices.stubs.crmr5100.Crmr5100AdditionalIdDetailResponse.Error> error = new Holder<>();  
                ws.crmr5100AdditionalIdDetail(request, response, error);  
                if (error.value == null && response.value != null) {  
                    Crmr5100AdditionalIdDetailResponse.Response res = response.value;  
                    // Do something with my response  
                 }  

Below snippet is the SOAP request that gets printed by my SOAPHandler in the console when I call the service on Jboss EAP 7 server

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">  
  <SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"/>  
  <soap:Body>  
    <ns2:Crmr5100AdditionalIdDetail xmlns:ns2="Crmr5100" clientId="AMORAM" clientPassword="XXXXX" comCfg="TCP myserv4sprhgend1 4275" command="OPEN">  
      <ImportImap1AdditionalId>  
        <Id>368638372002136</Id>  
        <AdditionalId>WQ0013966001</AdditionalId>  
      </ImportImap1AdditionalId>  
    </ns2:Crmr5100AdditionalIdDetail>  
  </soap:Body>  
</soap:Envelope>  

Below is the SOAP request generated for the same opeartion when I run the above code in a standalone java program (call the service in main method) or through SOAP UI, If you observe both the requests the first one is missing the tag and its contents merged into its predecessor tag

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">  
    <S:Body>  
        <ns2:Crmr5100AdditionalIdDetail xmlns:ns2="Crmr5100">  
            <request command="OPEN" clientId="AMORAM" clientPassword="XXXXX" comCfg="TCP myserv4sprhgend1 4275">  
                <ImportImap1AdditionalId>  
                    <Id>368638372002136</Id>  
                    <AdditionalId>WQ0013966001</AdditionalId>  
                </ImportImap1AdditionalId>  
            </request>  
        </ns2:Crmr5100AdditionalIdDetail>  
    </S:Body>  
</S:Envelope>  

I am not sure if this is an issue with the Jboss internal web services. I pasted my modules.xml to find out the jar that jboss uses.

modules.xml

<module xmlns="urn:jboss:module:1.3" name="org.apache.cxf.impl">

<properties>
    <property name="jboss.api" value="private"/>
</properties>

<resources>
    <resource-root path="cxf-rt-bindings-coloc-3.1.4.redhat-1.jar"/>
    <resource-root path="cxf-rt-bindings-object-3.1.4.redhat-1.jar"/>
    <resource-root path="cxf-rt-bindings-soap-3.1.4.redhat-1.jar"/>
    <resource-root path="cxf-rt-bindings-xml-3.1.4.redhat-1.jar"/>
    <resource-root path="cxf-rt-databinding-aegis-3.1.4.redhat-1.jar"/>
    <resource-root path="cxf-rt-databinding-jaxb-3.1.4.redhat-1.jar"/>
    <resource-root path="cxf-rt-frontend-jaxws-3.1.4.redhat-1.jar"/>
    <resource-root path="cxf-rt-frontend-simple-3.1.4.redhat-1.jar"/>
    <resource-root path="cxf-rt-management-3.1.4.redhat-1.jar"/>
    <resource-root path="cxf-rt-security-3.1.4.redhat-1.jar"/>
    <resource-root path="cxf-rt-security-saml-3.1.4.redhat-1.jar"/>
    <resource-root path="cxf-rt-transports-http-3.1.4.redhat-1.jar"/>
    <resource-root path="cxf-rt-transports-http-hc-3.1.4.redhat-1.jar"/>
    <resource-root path="cxf-rt-transports-jms-3.1.4.redhat-1.jar"/>
    <resource-root path="cxf-rt-transports-local-3.1.4.redhat-1.jar"/>
    <resource-root path="cxf-rt-wsdl-3.1.4.redhat-1.jar"/>
    <resource-root path="cxf-rt-ws-addr-3.1.4.redhat-1.jar"/>
    <resource-root path="cxf-rt-ws-mex-3.1.4.redhat-1.jar"/>
    <resource-root path="cxf-rt-ws-policy-3.1.4.redhat-1.jar"/>
    <resource-root path="cxf-rt-ws-rm-3.1.4.redhat-1.jar"/>
    <resource-root path="cxf-tools-common-3.1.4.redhat-1.jar"/>
    <resource-root path="cxf-tools-java2ws-3.1.4.redhat-1.jar"/>
    <resource-root path="cxf-tools-validator-3.1.4.redhat-1.jar"/>
    <resource-root path="cxf-tools-wsdlto-core-3.1.4.redhat-1.jar"/>
    <resource-root path="cxf-tools-wsdlto-databinding-jaxb-3.1.4.redhat-1.jar"/>
    <resource-root path="cxf-tools-wsdlto-frontend-jaxws-3.1.4.redhat-1.jar"/>
    <resource-root path="cxf-services-ws-discovery-api-3.1.4.redhat-1.jar"/>
    <resource-root path="cxf-xjc-boolean-3.0.5.redhat-1.jar"/>
    <resource-root path="cxf-xjc-bug986-3.0.5.redhat-1.jar"/>
    <resource-root path="cxf-xjc-dv-3.0.5.redhat-1.jar"/>
    <resource-root path="cxf-xjc-ts-3.0.5.redhat-1.jar"/>
    <resource-root path="cxf-xjc-runtime-3.0.5.redhat-1.jar"/>
</resources>
<dependencies>
 ...
</dependencies>

I looked at an existing post, and jboss community here one of them says that he regenerated with cxf (I would like to avoid if I can, unless I have to) but they are different issues I believe.

Any help is greatly appreciated.

Thanks,

Avi


Solution

  • I was actually trying to avoid re-generating the stubs but looks like Jboss EAP 7 uses CXF internally to run the services. Earlier when the stubs were generated using JAX-WS Jboss 5 was using JAX-WS internally.

    So the conclusion is any stubs that were generated using JAX-WS with this kind of services implementation has no other way but to re-generate the stubs with any of the stub generation tool. I used the Apache CXF and the generated stubs at least the Port.java file is way different

    /**
     * This class was generated by Apache CXF 3.1.10
     * 2017-04-07T11:01:43.951-05:00
     * Generated source version: 3.1.10
     * 
     */
    @WebService(targetNamespace = "Crmr5100", name = "Crmr5100Port")
    @XmlSeeAlso({ObjectFactory.class})
    @SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
    public interface Crmr5100Port {
    
        @WebMethod(operationName = "Crmr5100AdditionalIdDetail", action = "Crmr5100")
        @WebResult(name = "Crmr5100AdditionalIdDetailResponse", targetNamespace = "Crmr5100", partName = "Crmr5100AdditionalIdDetail")
        public Crmr5100AdditionalIdDetailResponse crmr5100AdditionalIdDetail(
            @WebParam(partName = "Crmr5100AdditionalIdDetail", name = "Crmr5100AdditionalIdDetail", targetNamespace = "Crmr5100")
            Crmr5100AdditionalIdDetail crmr5100AdditionalIdDetail
        );
    }
    

    And then the SOAP request is generated in the right format.

    I know that my actual question was to find a solution without re-generating the stubs. Because there is no other way other than to re-generating the stubs, I think the way I fixed was the only way. So marking it as answered. Please correct if I am wrong.

    Thanks, Avinash