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