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=9818>.
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=9818

Can not return polymorphic object relations

           Summary: Can not return polymorphic object relations
           Product: Axis
           Version: current (nightly)
          Platform: PC
        OS/Version: Windows NT/2K
            Status: NEW
          Severity: Critical
          Priority: Other
         Component: Serialization/Deserialization
        AssignedTo: [EMAIL PROTECTED]
        ReportedBy: [EMAIL PROTECTED]


My WebService is written in C# (.NET) and hosted by MS-IIS. I am using Axis for 
generating the client proxy.

For illustrating this problem, I have created the following scenario:
  - The WebService defines two objects, A (ancestor) & B (descendant)
  - The WebService defines one method, public A GetB(), but the implementation 
returns an instance of B

When running the Client I get an SAX Exception telling me that there is no 
element named ‘b’ in object A! It does not seem like Axis is using the actual 
type returned from the WebService call? (<GetBResult xsi:type="B">)


For reference I have added:
  1) The WebService (C#)
  2) The wsdl file
  3) The Client (Java)
  4) The exception that occurs when running the Client
  5) TCPMonitor - request
  6) TCPMonitor - response


1) The WebService (C#):
-----------------------------------------------------
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Web;
using System.Web.Services;
using System.Xml.Serialization;

namespace WebService2
{
  [WebService(Namespace="http://nib.dk/WS123/";)]
  public class Service1 : System.Web.Services.WebService
  {
    [WebMethod]
    [XmlInclude(typeof(B))]
    public A GetB()
    {
      B b = new B();
      b.a = "GetB; name of A";
      b.b = "GetB; name of B";

      return b;
    }
  }

  public class A
  {
    public string a;
  }

  [XmlInclude(typeof(B))]
  public class B : A
  {
    public string b;
  }
}
-----------------------------------------------------


2) The wsdl file:
-----------------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<definitions xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"; 
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"; 
xmlns:s="http://www.w3.org/2001/XMLSchema"; xmlns:s0="http://nib.dk/WS123/"; 
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"; 
xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/"; 
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"; 
targetNamespace="http://nib.dk/WS123/"; xmlns="http://schemas.xmlsoap.org/wsdl/";>
  <types>
    <s:schema elementFormDefault="qualified" 
targetNamespace="http://nib.dk/WS123/";>
      <s:element name="GetB">
        <s:complexType />
      </s:element>
      <s:element name="GetBResponse">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="GetBResult" 
type="s0:A" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:complexType name="A">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="1" name="a" type="s:string" />
        </s:sequence>
      </s:complexType>
      <s:complexType name="B">
        <s:complexContent mixed="false">
          <s:extension base="s0:A">
            <s:sequence>
              <s:element minOccurs="0" maxOccurs="1" name="b" type="s:string" />
            </s:sequence>
          </s:extension>
        </s:complexContent>
      </s:complexType>
      <s:element name="A" nillable="true" type="s0:A" />
    </s:schema>
  </types>
  <message name="GetBSoapIn">
    <part name="parameters" element="s0:GetB" />
  </message>
  <message name="GetBSoapOut">
    <part name="parameters" element="s0:GetBResponse" />
  </message>
  <message name="GetBHttpGetIn" />
  <message name="GetBHttpGetOut">
    <part name="Body" element="s0:A" />
  </message>
  <message name="GetBHttpPostIn" />
  <message name="GetBHttpPostOut">
    <part name="Body" element="s0:A" />
  </message>
  <portType name="Service1Soap">
    <operation name="GetB">
      <input message="s0:GetBSoapIn" />
      <output message="s0:GetBSoapOut" />
    </operation>
  </portType>
  <portType name="Service1HttpGet">
    <operation name="GetB">
      <input message="s0:GetBHttpGetIn" />
      <output message="s0:GetBHttpGetOut" />
    </operation>
  </portType>
  <portType name="Service1HttpPost">
    <operation name="GetB">
      <input message="s0:GetBHttpPostIn" />
      <output message="s0:GetBHttpPostOut" />
    </operation>
  </portType>
  <binding name="Service1Soap" type="s0:Service1Soap">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http"; 
style="document" />
    <operation name="GetB">
      <soap:operation soapAction="http://nib.dk/WS123/GetB"; style="document" />
      <input>
        <soap:body use="literal" />
      </input>
      <output>
        <soap:body use="literal" />
      </output>
    </operation>
  </binding>
  <binding name="Service1HttpGet" type="s0:Service1HttpGet">
    <http:binding verb="GET" />
    <operation name="GetB">
      <http:operation location="/GetB" />
      <input>
        <http:urlEncoded />
      </input>
      <output>
        <mime:mimeXml part="Body" />
      </output>
    </operation>
  </binding>
  <binding name="Service1HttpPost" type="s0:Service1HttpPost">
    <http:binding verb="POST" />
    <operation name="GetB">
      <http:operation location="/GetB" />
      <input>
        <mime:content type="application/x-www-form-urlencoded" />
      </input>
      <output>
        <mime:mimeXml part="Body" />
      </output>
    </operation>
  </binding>
  <service name="Service1">
    <port name="Service1Soap" binding="s0:Service1Soap">
      <soap:address location="http://localhost/WebService2/Service1.asmx"; />
    </port>
    <port name="Service1HttpGet" binding="s0:Service1HttpGet">
      <http:address location="http://localhost/WebService2/Service1.asmx"; />
    </port>
    <port name="Service1HttpPost" binding="s0:Service1HttpPost">
      <http:address location="http://localhost/WebService2/Service1.asmx"; />
    </port>
  </service>
</definitions>
-----------------------------------------------------


3) The Client (Java):
-----------------------------------------------------
import dk.nib.*;

public class Client {
  public static void main(String[] args) {
    Service1 sl = new Service1Locator();

    Service1Soap ss = null;
    try {
      ss = sl.getService1Soap();
    } catch (javax.xml.rpc.ServiceException e) {
      System.out.println("Error getting Service1Soap.; "+e);
      return;
    }

    try {
      A a = ss.getB();

      if (a instanceof B) {
        B b = (B)a;
        System.out.println("getB(); a="+b.getA()+", b="+b.getB());
      } else
        throw new Exception("Unexpected return type!");
    } catch (Exception e) {
      System.out.println("Error during call to getB().; "+e);
    }
  }
}
-----------------------------------------------------


4) The exception that occurs when running the Client:
-----------------------------------------------------
org.xml.sax.SAXException: Invalid element in dk.nib.A - b
        at org.apache.axis.encoding.ser.BeanDeserializer.onStartChild
(BeanDeserializer.java:270)
        at org.apache.axis.encoding.DeserializationContextImpl.startElement
(DeserializationContextImpl.java:862)
        at org.apache.axis.message.SAX2EventRecorder.replay
(SAX2EventRecorder.java:199)
        at org.apache.axis.message.MessageElement.publishToHandler
(MessageElement.java:636)
        at org.apache.axis.message.RPCElement.deserialize(RPCElement.java:232)
        at org.apache.axis.message.RPCElement.getParams(RPCElement.java:256)
        at org.apache.axis.client.Call.invoke(Call.java:1727)
        at org.apache.axis.client.Call.invoke(Call.java:1635)
        at org.apache.axis.client.Call.invoke(Call.java:1184)
        at dk.nib.Service1SoapStub.getB(Service1SoapStub.java:128)
        at dk.es.KMSWSClient.Client3.main(Client3.java:34)
Error during call to getB().; org.xml.sax.SAXException: Invalid element in 
dk.nib.A - b
-----------------------------------------------------


5) TCPMonitor - request:
-----------------------------------------------------
POST /WebService2/Service1.asmx HTTP/1.0
Content-Length: 311
Host: localhost
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://nib.dk/WS123/GetB";

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"; 
xmlns:xsd="http://www.w3.org/2001/XMLSchema"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";>
 <SOAP-ENV:Body>
  <GetB xmlns="http://nib.dk/WS123/"/>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
-----------------------------------------------------


6) TCPMonitor - response:
-----------------------------------------------------
HTTP/1.1 200 OK
Server: Microsoft-IIS/5.0
Date: Wed, 12 Jun 2002 20:23:06 GMT
Cache-Control: private, max-age=0
Content-Type: text/xml; charset=utf-8
Content-Length: 386

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xmlns:xsd="http://www.w3.org/2001/XMLSchema";>
  <soap:Body>
    <GetBResponse xmlns="http://nib.dk/WS123/";>
      <GetBResult xsi:type="B">
        <a>GetB; name of A</a>
        <b>GetB; name of B</b>
      </GetBResult>
    </GetBResponse>
  </soap:Body>
</soap:Envelope>
-----------------------------------------------------

Reply via email to