Hi

I got an issue with casting arrays returned when calling my SOAP service.


Interface:
public Address[] lookupAddress(...);

Implementation:
public Address[] lookupAddress(...) {
  ... some stuff happening ...
  UKAddress address = new UKAddress[10];
  ... 10 UKAddress objects added to address array ...
  return address;
}

Model:
public class BaseModel{}
public class Address{} extends BaseModel
public class UKAddress extends Address{}


Spring setup:
<bean id="addressLookupService" class="com.surgex.addresslookup.service.impl.AddressLookupServiceImpl" i nit-method="init">
   <property name="addressLookupDAO" ref="addressLookupDAO" />        
</bean>
        
<jaxws:endpoint id="soapService" implementor="#addressLookupService" address="/AddressLookup">
   <jaxws:serviceFactory>
      <ref bean="jaxws-and-aegis-service-factory"/>
   </jaxws:serviceFactory>        
</jaxws:endpoint>
        
<bean id="aegisBean" class="org.apache.cxf.aegis.databinding.AegisDatabinding"/> <bean id="jaxws-and-aegis-service-factory" class="org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean">
      <property name="dataBinding" ref="aegisBean"/>
      <property name="serviceConfigurations">
         <list>
<bean class="org.apache.cxf.jaxws.support.JaxWsServiceConfiguration"/> <bean class="org.apache.cxf.aegis.databinding.AegisServiceConfiguration"/> <bean class="org.apache.cxf.service.factory.DefaultServiceConfiguration"/>
         </list>
      </property>
      <property name="properties">
         <map>
            <entry key="writeXsiType">
               <value type="java.lang.Boolean">true</value>
            </entry>
            <entry key="overrideTypesList">
               <list>
<value>com.surgex.addresslookup.model.BaseModel</ value>
                  <value>com.surgex.addresslookup.model.Address</value>
<value>com.surgex.addresslookup.model.UKAddress</ value>
               </list>
            </entry>
         </map>
      </property>         
</bean>   

Note: the client side also has the <property name="properties"> setup as per the server above.

WSDL:
    <xsd:complexType name="ArrayOfUKAddress">
        <xsd:sequence>
<xsd:element maxOccurs="unbounded" minOccurs="0" name="UKAddress" nillable="true" type="tns:UKAddress"/>
        </xsd:sequence>
    </xsd:complexType>

    <xsd:complexType name="ArrayOfAddress">
        <xsd:sequence>
<xsd:element maxOccurs="unbounded" minOccurs="0" name="Address" nillable="true" type="tns:Address"/>
        </xsd:sequence>

    </xsd:complexType>

    <xsd:complexType abstract="true" name="BaseModel"/>

    <xsd:complexType name="Address">
        <xsd:complexContent>
            <xsd:extension base="tns:BaseModel">
                <xsd:sequence>

<xsd:element minOccurs="0" name="country" nillable="true" type="xsd:string"/> <xsd:element minOccurs="0" name="matchingAttributes" type="xsd:int"/>
                </xsd:sequence>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>

    <xsd:complexType name="UKAddress">
        <xsd:complexContent>
            <xsd:extension base="tns:Address">

                <xsd:sequence>
<xsd:element minOccurs="0" name="building" nillable="true" type="xsd:string"/> <xsd:element minOccurs="0" name="dbleDependentLocality" nillable="true" type="xsd:string"/> <xsd:element minOccurs="0" name="department" nillable="true" type="xsd:string"/> <xsd:element minOccurs="0" name="dependentLocality" nillable="true" type="xsd:string"/> <xsd:element minOccurs="0" name="dependentThoroughfare" nillable="true" type="xsd:string"/> <xsd:element minOccurs="0" name="matchingAttributes" type="xsd:int"/> <xsd:element minOccurs="0" name="organisation" nillable="true" type="xsd:string"/> <xsd:element minOccurs="0" name="poBox" nillable="true" type="xsd:string"/>

<xsd:element minOccurs="0" name="postalCode" nillable="true" type="xsd:string"/> <xsd:element minOccurs="0" name="postalTown" nillable="true" type="xsd:string"/> <xsd:element minOccurs="0" name="subBuilding" nillable="true" type="xsd:string"/> <xsd:element minOccurs="0" name="thoroughfare" nillable="true" type="xsd:string"/>
                </xsd:sequence>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>


The issue is that when using SOAP to access this service (Note that this service is also exposed through RMI, JMX, HttpInvoker, Hessian and Burlap and they're all fine) I cannot cast the Address[] to a UKAddress[] eventhough all elements in the Address[] are UKAddress objects.
I get a ClassCastException.

I have the same bunch of tests which are executed using RMI, JMX, HttpInvoker, Burlap and Hessian and they have no issue with the cast.

Address[] addresses = service.lookupAddress(...);
UKAddress[] addr = (UKAddress[])addresses    -> ClassCastException;

Code below runs ok.
Address[] addresses = service.lookupAddress(...);
assertTrue(addresses instanceof Address[]);
System.out.println(addresses.length);
for (int i=0; i<addresses.length; i++)
{
   assert(addresses[i] instanceof UKAddress);
   UKAddress addr = (UKAddress)addresses[i];
   System.out.println(addr);
}

How can I get that cast to work with SOAP?

Thx.

--
Frederic P. Soulier
OpenPGP key available on http://pgpkeys.mit.edu/
1024D/BA6700ED   49A6 8E8E 4230 8D41 1ADE  B649 3203 1DD2 BA67 00ED

Reply via email to