1 Reply Latest reply on Apr 18, 2017 4:41 PM by avinashmoram

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

    avinashmoram

      Hi,

       

      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.gov: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 incorrect 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 correct SOAP request generated for the same operation 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 <request> 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>
      

       

      incorrect soap request hit results in error response

      <ns2:Crmr5100AdditionalIdDetail xmlns:ns2="Crmr5100" clientId="AMORAM" clientPassword="XXXXX" comCfg="TCP myserv4sprhgend1 4275" command="OPEN">

      correct soap request, results in good response

      <ns2:Crmr5100AdditionalIdDetail xmlns:ns2="Crmr5100">

                  <request command="OPEN" clientId="AMORAM" clientPassword="XXXXX" comCfg="TCP myserv4sprhgend1 4275">

       

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

       

      I looked at the existing posts, Upgrading from AS 5.1 to AS 6 WS error  and Error calling HTTPS Webservice  but they are different issues I believe.

       

      Any help is greatly appreciated.

      Thanks,

      Avi

       

      Message was edited by: Avinash M

        • 1. Re: Jboss EAP 7 Webservice issue "Could not unwrap Operation", Incorrect SOAP request is generated
          avinashmoram

          After extensive research and trail and error I have found that there is no way just to re-use the existing stubs as Jboss EAP 7 uses Apache CXF in the background to run its web services.

           

          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.