Hi

I'm experiencing some very strange behavior when using Axis to transfer some simple data objects. The problem is an object which contains two string fields and one double string. I have however created a simplified example which shows the same error. I have this simple bean:

package axistest;

/**
* @author André Næss ([EMAIL PROTECTED])
*/
public class StringPackage {

   String onestring;
   String twostring;

   public StringPackage(String onestring, String twostring) {
       this.onestring = onestring;
       this.twostring = twostring;
   }

   public String getOnestring() {
       return onestring;
   }

   public void setOnestring(String onestring) {
       this.onestring = onestring;
   }

   public String getTwostring() {
       return twostring;
   }

   public void setTwostring(String twostring) {
       this.twostring = twostring;
   }

   public String toString() {
       return "onestring=" + onestring + ", twostring=" + twostring;
   }

}

And the following service:

package axistest;

/**
* @author André Næss ([EMAIL PROTECTED])
*/
public class AxisTest {

public StringPackage getStrings() {
return new StringPackage("onestring", "twostring");
}
}


My deployment file:

<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns="http://xml.apache.org/axis/wsdd/"; xmlns:java="http://xml.apache.org/axis/wsdd/providers/java";>


 <beanMapping
   xmlns:ns="urn:AxisTest"
   qname="ns:StringPackage"
   languageSpecificType="java:axistest.StringPackage"/>

 <service name="AxisTest" provider="java:RPC">
   <parameter name="className" value="axistest.AxisTest"/>
   <parameter name="allowedMethods" value="*"/>
 </service>

</deployment>

And finally, my test client:

package axistest;

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.ser.BeanSerializerFactory;
import org.apache.axis.encoding.ser.BeanDeserializerFactory;

import javax.xml.rpc.ServiceException;
import javax.xml.namespace.QName;
import java.rmi.RemoteException;

/**
* @author André Næss ([EMAIL PROTECTED])
*/
public class AxisTestClient {

   public static void main(String[] _) {

       try {

           QName qname = new QName("urn:AxisTest", "StringPackage");

           Service service = new Service();
           Call call = (Call) service.createCall();

call.registerTypeMapping(StringPackage.class,
qname,
new BeanSerializerFactory(StringPackage.class, qname),
new BeanDeserializerFactory(StringPackage.class, qname));


call.setTargetEndpointAddress("http://localhost:4545/axistest/services/AxisTest";);
call.setOperationName(new QName("urn:CO2PricesServiceServer", "getStrings"));
StringPackage result = (StringPackage) call.invoke(new Object[]{});
System.out.println("Result from web service:";);
System.out.println("result = " + result);


           AxisTest local = new AxisTest();
           StringPackage localResult = local.getStrings();
           System.out.println("Result from local object:");
           System.out.println("localResult = " + localResult);

       } catch (ServiceException e) {
           e.printStackTrace();
           throw new RuntimeException(e);
       } catch (RemoteException e) {
           e.printStackTrace();
           throw new RuntimeException(e);
       }
   }
}

Calling the client results in this output:

Result from web service:
result = onestring=onestring, twostring=onestring
Result from local object:
localResult = onestring=onestring, twostring=twostring

Inspecting the data that actually goes over the wire shows that they are as expected:

HTTP/1.1 200 OK
Content-Type: text/xml;charset=utf-8
Date: Fri, 15 Apr 2005 13:09:30 GMT
Server: Apache-Coyote/1.1
Connection: close

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"; xmlns:xsd="http://www.w3.org/2001/XMLSchema"; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";>
<soapenv:Body>
<ns1:getStringsResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"; xmlns:ns1="AxisTest">
<getStringsReturn href="#id0"/>
</ns1:getStringsResponse>
<multiRef id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"; xsi:type="ns2:StringPackage" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"; xmlns:ns2="urn:AxisTest">
<onestring xsi:type="soapenc:string">onestring</onestring>
<twostring xsi:type="soapenc:string">twostring</twostring>
</multiRef>
</soapenv:Body>
</soapenv:Envelope>


So the problem is clearly with the deserialization in the client. The problem seems to be that when Axis is deserializing the object it fails to resolve the fields correctly, and instead use the type to figure out what parameter it is looking at. I used a debugger to step through the Axis code, and it looked to me like Axis was not able to find a proper QName for the fields onestring and twostring, and falls back to testing the type. But because the type is the same in both cases (String) this results in the wrong value.

Even if I have configured something wrong (which is quite likely, seeing as I don't really understand deploy.wsdd and the qname and namespace concept) I still think this must be a bug in Axis because it would be better if it failed and threw some sort of exception rather than mangle my data.

I hope someone can have a look at this. It would also be great if someone else could try this code out and see if they experience the same problems.

I'm running Axis 1.2RC3 on Tomcat5. I was not able to try with Axis 1.1 because of issues after installing JRE5.0. (As soon as I get it uninstalled I'll try again).

--
André Næss

Reply via email to