Axis
  1. Axis
  2. AXIS-2396

two operations with same input/output type not getting invoked correctly

    Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Critical Critical
    • Resolution: Unresolved
    • Affects Version/s: 1.3
    • Fix Version/s: None
    • Component/s: Basic Architecture
    • Labels:
      None
    • Environment:
      OS-Windows XP
      Container-Weblogic(8.1 sp4)
      java:1.4.2

      Description

      I used WSDL2Java to generate web services stub and classes. It correctly generated three methods

      public MyResponse createReservation(Reservation body);
      public MyResponse adjustReservation(Reservation body);
      public AnotherRespose checkAvailability(Status body);

      When I invoked the adjustReservation web service using Axis Client, createReservation gets executed. I have debugged it in eclipse and for some reason, RPCProvider invokes createReservation eventhough MessageContext has correct SoapActionURI which is AdjustReservation.

      checkAvailability operation gets called correctly.

      It seems to be a bug for it can not handle methods with different names but same input/output type.

        Activity

        Hide
        Prabhat Jha added a comment -

        I found out after looking into the RPCProvider.java that it does not match SOAP URN while figuring out which method to invoke. In this case, it found CrateReservation and it called this everytime.

        The work around( I am not sure it's a work around or that's way you have to do it in Axis--I could not find the documentation) is that your operation name has to match it's input message name. For example:

        <wsdl:operation name="CreateReservation">
        <wsdl:input message="r-ws:CreateReservation"/>
        <wsdl:output message="r-ws:CreateReservationResponse"/>
        </wsdl:operation>

        Do the same for other operations and it works. I am not sure why AXIS team decided to go this way. I need some insight into this and I would appreciate if anybody can.

        Regards,
        Prabhat

        Show
        Prabhat Jha added a comment - I found out after looking into the RPCProvider.java that it does not match SOAP URN while figuring out which method to invoke. In this case, it found CrateReservation and it called this everytime. The work around( I am not sure it's a work around or that's way you have to do it in Axis--I could not find the documentation) is that your operation name has to match it's input message name. For example: <wsdl:operation name="CreateReservation"> <wsdl:input message="r-ws:CreateReservation"/> <wsdl:output message="r-ws:CreateReservationResponse"/> </wsdl:operation> Do the same for other operations and it works. I am not sure why AXIS team decided to go this way. I need some insight into this and I would appreciate if anybody can. Regards, Prabhat
        Hide
        Bjorn Townsend added a comment -

        I've checked the WSDL spec, and it clearly agrees with you (see section 2.3.5, at http://www.w3.org/TR/wsdl#_names ). Furthermore, it looks like Axis agrees with you too! One of the examples in the Axis User Guide shows an operation whose name attribute differs from the name attribute of the input element as well.

        Since you, the WSDL spec and the Axis docs all seem to agree, I tried to reproduce this issue on my own and wasn't able to. Can you provide a reproduction/test case that shows the problem?

        Thanks,
        Bjorn

        Show
        Bjorn Townsend added a comment - I've checked the WSDL spec, and it clearly agrees with you (see section 2.3.5, at http://www.w3.org/TR/wsdl#_names ). Furthermore, it looks like Axis agrees with you too! One of the examples in the Axis User Guide shows an operation whose name attribute differs from the name attribute of the input element as well. Since you, the WSDL spec and the Axis docs all seem to agree, I tried to reproduce this issue on my own and wasn't able to. Can you provide a reproduction/test case that shows the problem? Thanks, Bjorn
        Hide
        Gilberto Ribeiro Olimpio added a comment -

        I had the same problem with a webservice that i migrate from wasp to axis.
        I couldn't change the wsdl because I needed to keep the compatibility.

        I used a WSDD file with this service:


        <service name="Login" provider="java:RPC" style="document" use="literal">
        <parameter name="wsdlTargetNamespace" value="http://mdsla.com/wsdl" />
        <parameter name="wsdlServiceElement" value="Login" />
        <parameter name="schemaQualified"
        value="http://idoox.com/interface,http://systinet.com/xsd/SchemaTypes/" />
        <parameter name="wsdlServicePort" value="Login" />
        <parameter name="className" value="com.mdsb.cea.ws.Login" />
        <parameter name="wsdlPortType" value="Login" />
        <parameter name="typeMappingVersion" value="1.2" />
        <operation name="validar" qname="validar"
        returnQName="retNS:string_Response"
        xmlns:retNS="http://systinet.com/xsd/SchemaTypes/"
        returnType="rtns:string" xmlns:rtns="http://www.w3.org/2001/XMLSchema"
        soapAction="http://mdsla.com/wsdlLogin#validar#KExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZzs=">
        <parameter qname="pns:p0" xmlns:pns="http://systinet.com/xsd/SchemaTypes/"
        type="tns:string" xmlns:tns="http://www.w3.org/2001/XMLSchema" />
        </operation>
        <operation name="encerrar" qname="encerrar"
        returnQName="retNS:string_Response"
        xmlns:retNS="http://systinet.com/xsd/SchemaTypes/"
        returnType="rtns:string" xmlns:rtns="http://www.w3.org/2001/XMLSchema"
        soapAction="http://mdsla.com/wsdlLogin#encerrar#KExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZzs=">
        <parameter qname="pns:p0" xmlns:pns="http://systinet.com/xsd/SchemaTypes/"
        type="tns:string" xmlns:tns="http://www.w3.org/2001/XMLSchema" />
        </operation>
        <parameter name="allowedMethods" value="encerrar validar" />
        </service>


        Note that I have the same input type (pns:p0) for the 2 operations (encerrar, validar).

        The problem with Axis is that it doesn't check the soapAction and (in this case) it allways use the first operation.

        To solve this problem I change the method:
        public OperationDesc [] getPossibleOperationsByQName(QName qname) throws AxisFault
        (in the class: org.apache.axis.MessageContext)

        The original code:

        } else {
        // DOCUMENT Style
        // Get all of the operations that have qname as
        // a possible parameter QName
        ArrayList allOperations = desc.getOperations();
        ArrayList foundOperations = new ArrayList();
        for (int i=0; i < allOperations.size(); i++ ) {
        OperationDesc tryOp =
        (OperationDesc) allOperations.get;
        if (tryOp.getParamByQName(qname) != null)

        { foundOperations.add(tryOp); }


        }
        if (foundOperations.size() > 0)

        { possibleOperations = (OperationDesc[]) JavaUtils.convert(foundOperations, OperationDesc[].class); }
        }



        The changed code:



        } else {
        // DOCUMENT Style
        // Get all of the operations that have qname as
        // a possible parameter QName
        ArrayList allOperations = desc.getOperations();
        ArrayList foundOperations = new ArrayList();
        for (int i=0; i < allOperations.size(); i++ ) {
        OperationDesc tryOp =
        (OperationDesc) allOperations.get;
        if (tryOp.getParamByQName(qname) != null) { if (!useSOAPAction() || (useSOAPAction() && tryOp.getSoapAction().equals(getSOAPActionURI()))) foundOperations.add(tryOp); }
        }
        if (foundOperations.size() > 0) { possibleOperations = (OperationDesc[]) JavaUtils.convert(foundOperations, OperationDesc[].class); }


        }

        In the changed code, I check for the soapAction, if there is one, I use it to know what operation was called.

        Thanks,

        Gilberto

        Show
        Gilberto Ribeiro Olimpio added a comment - I had the same problem with a webservice that i migrate from wasp to axis. I couldn't change the wsdl because I needed to keep the compatibility. I used a WSDD file with this service: <service name="Login" provider="java:RPC" style="document" use="literal"> <parameter name="wsdlTargetNamespace" value="http://mdsla.com/wsdl" /> <parameter name="wsdlServiceElement" value="Login" /> <parameter name="schemaQualified" value="http://idoox.com/interface, http://systinet.com/xsd/SchemaTypes/ " /> <parameter name="wsdlServicePort" value="Login" /> <parameter name="className" value="com.mdsb.cea.ws.Login" /> <parameter name="wsdlPortType" value="Login" /> <parameter name="typeMappingVersion" value="1.2" /> <operation name="validar" qname="validar" returnQName="retNS:string_Response" xmlns:retNS="http://systinet.com/xsd/SchemaTypes/" returnType="rtns:string" xmlns:rtns="http://www.w3.org/2001/XMLSchema" soapAction="http://mdsla.com/wsdlLogin#validar#KExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZzs="> <parameter qname="pns:p0" xmlns:pns="http://systinet.com/xsd/SchemaTypes/" type="tns:string" xmlns:tns="http://www.w3.org/2001/XMLSchema" /> </operation> <operation name="encerrar" qname="encerrar" returnQName="retNS:string_Response" xmlns:retNS="http://systinet.com/xsd/SchemaTypes/" returnType="rtns:string" xmlns:rtns="http://www.w3.org/2001/XMLSchema" soapAction="http://mdsla.com/wsdlLogin#encerrar#KExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZzs="> <parameter qname="pns:p0" xmlns:pns="http://systinet.com/xsd/SchemaTypes/" type="tns:string" xmlns:tns="http://www.w3.org/2001/XMLSchema" /> </operation> <parameter name="allowedMethods" value="encerrar validar" /> </service> Note that I have the same input type (pns:p0) for the 2 operations (encerrar, validar). The problem with Axis is that it doesn't check the soapAction and (in this case) it allways use the first operation. To solve this problem I change the method: public OperationDesc [] getPossibleOperationsByQName(QName qname) throws AxisFault (in the class: org.apache.axis.MessageContext) The original code: — } else { // DOCUMENT Style // Get all of the operations that have qname as // a possible parameter QName ArrayList allOperations = desc.getOperations(); ArrayList foundOperations = new ArrayList(); for (int i=0; i < allOperations.size(); i++ ) { OperationDesc tryOp = (OperationDesc) allOperations.get ; if (tryOp.getParamByQName(qname) != null) { foundOperations.add(tryOp); } } if (foundOperations.size() > 0) { possibleOperations = (OperationDesc[]) JavaUtils.convert(foundOperations, OperationDesc[].class); } } — The changed code: — } else { // DOCUMENT Style // Get all of the operations that have qname as // a possible parameter QName ArrayList allOperations = desc.getOperations(); ArrayList foundOperations = new ArrayList(); for (int i=0; i < allOperations.size(); i++ ) { OperationDesc tryOp = (OperationDesc) allOperations.get ; if (tryOp.getParamByQName(qname) != null) { if (!useSOAPAction() || (useSOAPAction() && tryOp.getSoapAction().equals(getSOAPActionURI()))) foundOperations.add(tryOp); } } if (foundOperations.size() > 0) { possibleOperations = (OperationDesc[]) JavaUtils.convert(foundOperations, OperationDesc[].class); } } — In the changed code, I check for the soapAction, if there is one, I use it to know what operation was called. Thanks, Gilberto

          People

          • Assignee:
            Unassigned
            Reporter:
            Prabhat Jha
          • Votes:
            1 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:

              Development