DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=10364>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=10364

RPCProvider.java handling of arrays

           Summary: RPCProvider.java handling of arrays
           Product: Axis
           Version: beta-2
          Platform: PC
        OS/Version: Windows NT/2K
            Status: NEW
          Severity: Normal
          Priority: Other
         Component: Basic Architecture
        AssignedTo: [EMAIL PROTECTED]
        ReportedBy: [EMAIL PROTECTED]


I have a web service which exposes the following Java method:

void addFiles(String session, DocServerFile[] files);

When calling this method from a .NET client, the Soap envelope looks as follows:

<?xml version="1.0" encoding="utf-8" ?> 
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"; 
   xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/";  
xmlns:tns="http://localhost:4040/jdedocserver/AxisServices/DocServerServices";
xmlns:types="http://localhost:4040/jdedocserver/AxisServices/DocServerServices/e
ncoded Types" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
xmlns:xsd="http://www.w3.org/2001/XMLSchema";>  
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/";>  
  <q1:addFiles xmlns:q1="addFiles">
    <session xsi:type="xsd:string">4c7d72e2368ef4697005e12002d547f9</session> 
    <files href="#id1" /> 
  </q1:addFiles>
  <soapenc:Array id="id1" xmlns:q2="DocServerServices" 
soapenc:arrayType="q2:DocServerFile[1]"> 
    <Item href="#id2" /> 
  </soapenc:Array>
  <q3:DocServerFile id="id2" xsi:type="q3:DocServerFile" 
                xmlns:q3="DocServerServices">
    <path xsi:type="xsd:string">/SampleRepository/Address Book/t.txt</path> 
    <contentType xsi:type="xsd:string">type</contentType> 
    <contentLength xsi:type="xsd:long">3</contentLength> 
    <content xsi:type="xsd:base64Binary">MTIz</content> 
  </q3:DocServerFile>
  </soap:Body>
</soap:Envelope>


Note that .NET encodes the array parameter outside the method name element 
<q1:addFiles>. This causes Axis to think that the <soapenc:Array> element 
following the method name, is a Soap Document style message and not an RPC 
style message.

I traced the problem to the following code in 
org.apache.axis.providers.java.RPCProvider.java:

            // If this is a regular old SOAPBodyElement, and it's a root,
            // we're probably a non-wrapped doc/lit service.  In this case,
            // we deserialize the element, and create an RPCElement "wrapper"
            // around it which points to the correct method.
            // FIXME : There should be a cleaner way to do this...
1            if (!(bodies.get(bNum) instanceof RPCElement)) {
2                SOAPBodyElement bodyEl = (SOAPBodyElement)bodies.get(bNum);
                // igors: better check if bodyEl.getID() != null
                // to make sure this loop does not step on SOAP-ENC objects
                // that follow the parameters! FIXME?
3                if (bodyEl.isRoot() && operation != null) {
4                    ParameterDesc param = operation.getParameter(bNum);
                    // at least do not step on non-existent parameters!
5                    if(param != null) {
6                        Object val = bodyEl.getValueAsType(param.getTypeQName
());
7                        body = new RPCElement("",
8                                              operation.getName(),
9                                              new Object [] { val });
10                    }
                ....


This code is looping over Soap body elements, and if it finds more than one 
body 
elements that are root, it assumes that the extra body elements are (according 
to the 
comments) "non-wrapped doc/lit service". This is not the case in this instance. 
The code incorrectly wraps the <soapenc:Array> element into an RPCElement and 
tries to invoke it (not shown above).

I was able to get around the problem by following "igors" advice in the 
comments, and changing the code in line 3 as follows:

if (bodyEl.isRoot() && operation != null && bodyEl.getID() == null) {

This is obviously a hack which fixes my problem. However, it looks like better 
handling of Document/RPC style encoding is needed.

Reply via email to