This is due to the WSDLs Axis generates when using RPC or Doc/Wrapped styles.
In the RPC case arrays are wrapped in XMLschema complexType while in the Doc/Wrapped case they are used as simple repeated element in the method response message declaration RPC) <wsdl:types> ... <complexType name="ArrayOf_tns2_XYZ"> <sequence> <element maxOccurs="unbounded" minOccurs="0" name="item" type="tns2:XYZ"/> </sequence> </complexType> </wsdl:types> ... <wsdl:message name="getArrayResponse"> <wsdl:part name="getArrayReturn" type="impl:ArrayOf_tns2_XYZ"/> </wsdl:message> Wrapped) <wsdl:types> ... <element name="getArrayResponse"> <complexType> <sequence> <element maxOccurs="unbounded" name="getArrayReturn" type="tns2:XYZ"/> </sequence> </complexType> </element> </wsdl:types> ... <wsdl:message name="getArrayResponse"> <wsdl:part element="impl:getArrayResponse" name="parameters"/> </wsdl:message> *** Unzipping my comment I've expaned a little bit more your example: ------ class MyWebService.java - XYZ..java public class MyWebService{ public XYZ[] getArray(){ return new XYZ[0]; } } public class XYZ { private String name; private int value; public XYZ(){ name=""; value=0; } public void setName(String name){ this.name=name; } public void setValue(int value){ this.value=value;} public String getName(){ return name; } public int getValue(){ return value; } } ------ I've then generated RPC/literal WSDL: java -cp $AXISCLASSPATH:. org.apache.axis.wsdl.Java2WSDL -o MyWebService.wsdl -l http://127.0.0.1:8080/MyWebService -n urn:MyWebService -pexample=urn:MyWebService -y RPC -u LITERAL MyWebService ------- MyWebService.wsdl.RPC-literal <?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions targetNamespace="urn:MyWebService" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="urn:MyWebService" xmlns:intf="urn:MyWebService" xmlns:tns2="http://DefaultNamespace" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="ht tp://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <!--WSDL created by Apache Axis version: 1.3 Built on Oct 05, 2005 (05:23:37 EDT)--> <wsdl:types> <schema targetNamespace="http://DefaultNamespace" xmlns="http://www.w3.org/2001/XMLSchema"> <import namespace="urn:MyWebService"/> <import namespace="http://schemas.xmlsoap.org/soap/encoding/"/> <complexType name="XYZ"> <sequence> <element name="name" nillable="true" type="xsd:string"/> <element name="value" type="xsd:int"/> </sequence> </complexType> </schema> <schema targetNamespace="urn:MyWebService" xmlns="http://www.w3.org/2001/XMLSchema"> <import namespace="http://DefaultNamespace"/> <import namespace="http://schemas.xmlsoap.org/soap/encoding/"/> <complexType name="ArrayOf_tns2_XYZ"> <sequence> <element maxOccurs="unbounded" minOccurs="0" name="item" type="tns2:XYZ"/> </sequence> </complexType> </schema> </wsdl:types> <wsdl:message name="getArrayRequest"> </wsdl:message> <wsdl:message name="getArrayResponse"> <wsdl:part name="getArrayReturn" type="impl:ArrayOf_tns2_XYZ"/> </wsdl:message> <wsdl:portType name="MyWebService"> <wsdl:operation name="getArray"> <wsdl:input message="impl:getArrayRequest" name="getArrayRequest"/> <wsdl:output message="impl:getArrayResponse" name="getArrayResponse"/> </wsdl:operation> </wsdl:portType> <wsdl:binding name="MyWebServiceSoapBinding" type="impl:MyWebService"> <wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="getArray"> <wsdlsoap:operation soapAction=""/> <wsdl:input name="getArrayRequest"> <wsdlsoap:body namespace="urn:MyWebService" use="literal"/> </wsdl:input> <wsdl:output name="getArrayResponse"> <wsdlsoap:body namespace="urn:MyWebService" use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="MyWebServiceService"> <wsdl:port binding="impl:MyWebServiceSoapBinding" name="MyWebService"> <wsdlsoap:address location="http://127.0.0.1:8080/MyWebService"/> </wsdl:port> </wsdl:service> </wsdl:definitions> ------- In this case note that Axis wraps the array of XYZ into an XML-schema complexType and use it as the return type of the getArray() method. <wsdl:message name="getArrayResponse"> <wsdl:part name="getArrayReturn" type="impl:ArrayOf_tns2_XYZ"/> </wsdl:message> where ArrayOf_tns2_XYZ is <complexType name="ArrayOf_tns2_XYZ"> <sequence> <element maxOccurs="unbounded" minOccurs="0" name="item" type="tns2:XYZ"/> </sequence> </complexType> In this case an array of 0 elements is correctly managed by Axis Serializer/Deserializer. ****** And there was evening, and there was morning... I've then generated WRAPPED WSDL: java -cp $AXISCLASSPATH:. org.apache.axis.wsdl.Java2WSDL -o MyWebService.wsdl -l http://127.0.0.1:8080/MyWebService -n urn:MyWebService -pexample=urn:MyWebService -y WRAPPED MyWebService ------ MyWebService.wsdl.WRAPPED <?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions targetNamespace="urn:MyWebService" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="urn:MyWebService" xmlns:intf="urn:MyWebService" xmlns:tns2="http://DefaultNamespace" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="ht tp://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <!--WSDL created by Apache Axis version: 1.3 Built on Oct 05, 2005 (05:23:37 EDT)--> <wsdl:types> <schema elementFormDefault="qualified" targetNamespace="urn:MyWebService" xmlns="http://www.w3.org/2001/XMLSchema"> <import namespace="http://DefaultNamespace"/> <element name="getArray"> <complexType/> </element> <element name="getArrayResponse"> <complexType> <sequence> <element maxOccurs="unbounded" name="getArrayReturn" type="tns2:XYZ"/> </sequence> </complexType> </element> </schema> <schema elementFormDefault="qualified" targetNamespace="http://DefaultNamespace" xmlns="http://www.w3.org/2001/XMLSchema"> <complexType name="XYZ"> <sequence> <element name="name" nillable="true" type="xsd:string"/> <element name="value" type="xsd:int"/> </sequence> </complexType> </schema> </wsdl:types> <wsdl:message name="getArrayRequest"> <wsdl:part element="impl:getArray" name="parameters"/> </wsdl:message> <wsdl:message name="getArrayResponse"> <wsdl:part element="impl:getArrayResponse" name="parameters"/> </wsdl:message> <wsdl:portType name="MyWebService"> <wsdl:operation name="getArray"> <wsdl:input message="impl:getArrayRequest" name="getArrayRequest"/> <wsdl:output message="impl:getArrayResponse" name="getArrayResponse"/> </wsdl:operation> </wsdl:portType> <wsdl:binding name="MyWebServiceSoapBinding" type="impl:MyWebService"> <wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="getArray"> <wsdlsoap:operation soapAction=""/> <wsdl:input name="getArrayRequest"> <wsdlsoap:body use="literal"/> </wsdl:input> <wsdl:output name="getArrayResponse"> <wsdlsoap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="MyWebServiceService"> <wsdl:port binding="impl:MyWebServiceSoapBinding" name="MyWebService"> <wsdlsoap:address location="http://127.0.0.1:8080/MyWebService"/> </wsdl:port> </wsdl:service> </wsdl:definitions> ------- As you can see in this case it doesn't wrap the Array in a complexType as in the RPC literal case (as I'd expect...) but it leaves it as a repeated element in the getArray response element: <element name="getArrayResponse"> <complexType> <sequence> <element maxOccurs="unbounded" name="getArrayReturn" type="tns2:XYZ"/> </sequence> </complexType> </element> In this case you get a NullPointerException if a 0 elements array is sent. Note that this happens also if you modify line <element maxOccurs="unbounded" name="getArrayReturn" type="tns2:XYZ"/> as <element maxOccurs="unbounded" minOccurs="0" name="getArrayReturn" type="tns2:XYZ"/>. *** My poor solution What I did in order to obtain a WRAPPED WSDL/SOAP solution working as I would expect was to manually edit the (WRAPPED) WSDL file wrapping the array in a complexType: <element name="getArrayResponse"> <complexType> <sequence> <element name="getArrayReturn" type="tns2:ArrayOfXYZ"/> </sequence> </complexType> </element> ... <complexType name="ArrayOfXYZ"> <sequence> <element maxOccurs="unbounded" minOccurs="0" name="item" type="tns2:XYZ"/> </sequence> </complexType> - *** Concluding... The same problem and solution would apply also to arrays passed as arguments of methods. Is it a bug ? Is it an error to assume Axis should wrap arrays when used as return/argument types in methods? Is there a way to force Axis to wrap arrays anyway? Personally I choose to work in RPC/literal mode in order to avoid the burden of manually editing the WSDL doc for fufure evolution and re-generations...