Issue Details (XML | Word | Printable)

Key: AXIS-2396
Type: Bug Bug
Status: Open Open
Priority: Critical Critical
Assignee: Unassigned
Reporter: Prabhat Jha
Votes: 1
Watchers: 2
Operations

If you were logged in you would be able to see more operations.
Axis

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

Created: 08/Feb/06 02:04 PM   Updated: 07/Mar/06 03:39 AM
Return to search
Component/s: Basic Architecture
Affects Version/s: 1.3
Fix Version/s: None

Time Tracking:
Not Specified

Environment:
OS-Windows XP
Container-Weblogic(8.1 sp4)
java:1.4.2


 Description  « Hide
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.

 All   Comments   Work Log   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Prabhat Jha added a comment - 09/Feb/06 08:14 AM
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

Bjorn Townsend added a comment - 15/Feb/06 09:27 AM
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

Gilberto Ribeiro Olimpio added a comment - 07/Mar/06 03:39 AM
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(i);
                        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(i);
                        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