You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-user@axis.apache.org by Davide Romanini <d....@cineca.it> on 2005/12/21 16:40:07 UTC

Empty responses with Axis 1.3

Hi,

I'm developing a Web Service using Axis 1.3. I've manually created the
WSDL and all Java classes and implementation. I DON'T want to use
wsdl2java, I already have all things right. I'm trying to setup a
correct server-config.wsdd configuration to bind Axis to my
implementation class.

I have a simple operation list:

public UID[] list();

The return type has been mapped in XSchema as ArrayOfCodes
<xsd:complexType name="ArrayOfCodes">
 <xsd:sequence>
  <xsd:element maxOccurs="unbounded" minOccurs="0" name="code" type="pub:Code"/>
 </xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Code"/>

Note that XSchema type Code is the equivalent of the Java marker
interface UID.

I then have a concret implementation of UID:

public class UIDImpl implements UID, Serializable
{
    private String value;
    private Date lastUpdateDate;
    // getters and setters ...
}

XSchema:
<xsd:complexType name="CodeImpl">
 <xsd:complexContent>
  <xsd:extension base="pub:Code">
   <xsd:all>
    <xsd:element maxOccurs="1" minOccurs="1" name="value" type="xsd:string"/>
    <xsd:element minOccurs="0" name="lastUpdateDate" type="xsd:dateTime"/>
   </xsd:all>
  </xsd:extension>
 </xsd:complexContent>
</xsd:complexType>

In wsdl the operation is defined as follows:

<wsdl:message name="listRequest" />
<wsdl:message name="listResponse">
 <wsdl:part name="codes" type="pub:ArrayOfCodes" />
</wsdl:message>
...
<wsdl:operation name="list">
 <wsdl:input message="pub:listRequest" name="listRequest"/>
 <wsdl:output message="pub:listResponse"/>
</wsdl:operation>
...
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
 <wsdl:operation name="list">
  <soap:operation soapAction="http://example.com/service#list"/>
  <wsdl:input>
   <soap:body namespace="http://example.com/service" use="literal"/>
  </wsdl:input>
  <wsdl:output>
   <soap:body namespace="http://example.com/service" use="literal"/>
  </wsdl:output>
</wsdl:operation>

I then made mappings in server-config.wsdd:

<operation name="list" returnQName="pub:codes" returnType="pub:ArrayOfCodes" />
<arrayMapping qname="pub:ArrayOfCodes"
 type="java:it.cineca.UID[]"
 innerType="pub:Code" />
<typeMapping qname="pub:Code"
 type="java:it.cineca.UID"
 serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
 deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory" />
 <typeMapping qname="pub:CodeImpl"
  type="java:it.cineca.mods.CodeImpl"
  serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
  deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory" />

I created a simple client that sends the following payload:

<?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"
 xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
 xmlns:ns4="http://example.com/service">
 <SOAP-ENV:Body>
  <ns4:list/>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

I see, from my application logs, that my method is correctly invoked by
Axis, but Axis replies to me just with HTTP/1.1 200 OK,
without any SOAP envelope :-(

I expect something like this:
<?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>
  <listResponse xmlns="http://example.com/service">
   <codes xsi:type="pub:ArrayOfCodes">
    <code xsi:type="pub:CodeImpl">
     <value>100</value>
     <lastUpdateDate>somedatetime</lastUpdateDate>
    </code>
    <code xsi:type="pub:CodeImpl">
     <value>100</value>
     <lastUpdateDate>anotherdatetime</lastUpdateDate>
    </code>
  </listResponse>
 </soapenv:Body>
</soapenv:Envelope>

What I'm wrong? I find strange that Axis doesn't return anything...

Thank in advance.

Bye,
Davide Romanini


Re: Empty responses with Axis 1.3

Posted by Davide Romanini <d....@cineca.it>.
Il giorno gio, 22/12/2005 alle 18.00 +0100, Davide Romanini ha scritto:

> More on that: I tested my service with Axis 1.2.1, 1.3, 1.4 (from
> nightly builds) and still have the same problem. I still don't
> understand why it can't find the serializer I defined and why it doesn't
> return any fault in response.
> 

Solved!!

The problem seems to be related to how ArraySerializer inspects the
array itself. If my method is like this:

public Code[] list()
{
	return new Code[] { new CodeImpl() };
}

then Axis looks for the Code serializer and NOT for the element
implementation serializer (CodeImpl).

If instead a make

public Code[] list()
{
	return new CodeImpl[] { new CodeImpl() };
}

the interface is still respected BUT now Axis works and loads the
CodeImpl serializer. That means also that Axis DOESN'T  work correctly
if you have inheritance:

public class CodeExtended extends CodeImpl {}

public Code[] list()
{
	return new CodeImpl[] { new CodeImpl(), new CodeExtended() };
}

Axis still uses the CodeImpl serializer for ALL elements inside the
array, so the second element will be accessed using the parent
interface. I really think this is a bug, Axis should load a serializer
based on implementation of the single elements.

Bye,
Davide Romanini 


Re: Empty responses with Axis 1.3

Posted by Davide Romanini <d....@cineca.it>.
Il giorno gio, 22/12/2005 alle 13.10 +0100, Davide Romanini ha scritto:

> I investigated a bit more about this issue. Looking to logs seems that
> Axis correctly starts to generate the response. It correctly loads the
> ArraySerializer configured for my return type. When it finds a single
> array object of type it.cineca.mods.UIDImpl, invokes serialize() on
> SerializationContext and throws 
> 
> java.io.IOException: No serializer found for class
> it.cineca.mods.UIDImpl in registry
> org.apache.axis.encoding.TypeMappingDelegate@4eb585
> 
> As you can see in my following post, I correctly configured a
> <typeMapping> element for this type, and Axis doesn't throw any
> exception while loading service configuration...
> 

More on that: I tested my service with Axis 1.2.1, 1.3, 1.4 (from
nightly builds) and still have the same problem. I still don't
understand why it can't find the serializer I defined and why it doesn't
return any fault in response.

Bye,
Davide Romanini


Re: Empty responses with Axis 1.3

Posted by Davide Romanini <d....@cineca.it>.
Il giorno mer, 21/12/2005 alle 17.39 -0500, Anne Thomas Manes ha
scritto:
> If you want ArrayOfCodes to contain CodeImpl rather than Code, then
> you must define the type that way:
> 
> <xsd:complexType name="ArrayOfCodes">
> <xsd:sequence>
>   <xsd:element maxOccurs="unbounded" minOccurs="0" name="code"
> type="pub:CodeImpl"/>
> </xsd:sequence>
> </xsd:complexType>
> 
> Otherwise, if you define the inner type as Code and you return
> CodeImpl, the client should generate an error that it found an
> unexpected type.. 
> 
> But that doesn't explain why your service doesn't return a SOAP
> envelope. I suggets you run wsdl2java and compare the skeleton code.
> 
> Anne
> 
I investigated a bit more about this issue. Looking to logs seems that
Axis correctly starts to generate the response. It correctly loads the
ArraySerializer configured for my return type. When it finds a single
array object of type it.cineca.mods.UIDImpl, invokes serialize() on
SerializationContext and throws 

java.io.IOException: No serializer found for class
it.cineca.mods.UIDImpl in registry
org.apache.axis.encoding.TypeMappingDelegate@4eb585

As you can see in my following post, I correctly configured a
<typeMapping> element for this type, and Axis doesn't throw any
exception while loading service configuration...

Someone can help?

Bye, 
Davide Romanini


Re: Empty responses with Axis 1.3

Posted by Davide Romanini <d....@cineca.it>.
Il giorno mer, 21/12/2005 alle 17.39 -0500, Anne Thomas Manes ha
scritto:
> If you want ArrayOfCodes to contain CodeImpl rather than Code, then
> you must define the type that way:
> 
> <xsd:complexType name="ArrayOfCodes">
> <xsd:sequence>
>   <xsd:element maxOccurs="unbounded" minOccurs="0" name="code"
> type="pub:CodeImpl"/>
> </xsd:sequence>
> </xsd:complexType>
> 
> Otherwise, if you define the inner type as Code and you return
> CodeImpl, the client should generate an error that it found an
> unexpected type.. 
> 
> But that doesn't explain why your service doesn't return a SOAP
> envelope. I suggets you run wsdl2java and compare the skeleton code.
> 
Mmmhh... I already used this approach to define a type Exp (marker
interface) with subtypes And, Or etc... I had a type Query made of
elements of type Exp and I didn't find any problem handling them. Since
I want to use the same interface to handle different types of Codes
(with different structure) I think this is correct.

Anyway I tried to do a wsdl2java. Generated code is similar to mine,
except for the fact that it doesn't create an empty interface for Code
and it defines the operation in this way:

<operation name="list" qname="pub:list" returnQName="codes"
returnType="pub:ArrayOfCodes" returnItemQName="pub:code"
soapAction="http://example.com/service#list" />

I tried to add the returnItemQName in my descriptor but the result is
the same :-(

Regards,
Davide Romanini



Re: Empty responses with Axis 1.3

Posted by Anne Thomas Manes <at...@gmail.com>.
If you want ArrayOfCodes to contain CodeImpl rather than Code, then you must
define the type that way:

<xsd:complexType name="ArrayOfCodes">
<xsd:sequence>
  <xsd:element maxOccurs="unbounded" minOccurs="0" name="code"
type="pub:CodeImpl"/>
</xsd:sequence>
</xsd:complexType>

Otherwise, if you define the inner type as Code and you return CodeImpl, the
client should generate an error that it found an unexpected type..

But that doesn't explain why your service doesn't return a SOAP envelope. I
suggets you run wsdl2java and compare the skeleton code.

Anne

On 12/21/05, Davide Romanini <d....@cineca.it> wrote:
>
> Hi,
>
> I'm developing a Web Service using Axis 1.3. I've manually created the
> WSDL and all Java classes and implementation. I DON'T want to use
> wsdl2java, I already have all things right. I'm trying to setup a
> correct server-config.wsdd configuration to bind Axis to my
> implementation class.
>
> I have a simple operation list:
>
> public UID[] list();
>
> The return type has been mapped in XSchema as ArrayOfCodes
> <xsd:complexType name="ArrayOfCodes">
> <xsd:sequence>
>   <xsd:element maxOccurs="unbounded" minOccurs="0" name="code"
> type="pub:Code"/>
> </xsd:sequence>
> </xsd:complexType>
> <xsd:complexType name="Code"/>
>
> Note that XSchema type Code is the equivalent of the Java marker
> interface UID.
>
> I then have a concret implementation of UID:
>
> public class UIDImpl implements UID, Serializable
> {
>     private String value;
>     private Date lastUpdateDate;
>     // getters and setters ...
> }
>
> XSchema:
> <xsd:complexType name="CodeImpl">
> <xsd:complexContent>
>   <xsd:extension base="pub:Code">
>    <xsd:all>
>     <xsd:element maxOccurs="1" minOccurs="1" name="value"
> type="xsd:string"/>
>     <xsd:element minOccurs="0" name="lastUpdateDate" type="xsd:dateTime"/>
>    </xsd:all>
>   </xsd:extension>
> </xsd:complexContent>
> </xsd:complexType>
>
> In wsdl the operation is defined as follows:
>
> <wsdl:message name="listRequest" />
> <wsdl:message name="listResponse">
> <wsdl:part name="codes" type="pub:ArrayOfCodes" />
> </wsdl:message>
> ...
> <wsdl:operation name="list">
> <wsdl:input message="pub:listRequest" name="listRequest"/>
> <wsdl:output message="pub:listResponse"/>
> </wsdl:operation>
> ...
> <soap:binding style="rpc" transport="
> http://schemas.xmlsoap.org/soap/http"/>
> <wsdl:operation name="list">
>   <soap:operation soapAction="http://example.com/service#list"/>
>   <wsdl:input>
>    <soap:body namespace="http://example.com/service" use="literal"/>
>   </wsdl:input>
>   <wsdl:output>
>    <soap:body namespace="http://example.com/service" use="literal"/>
>   </wsdl:output>
> </wsdl:operation>
>
> I then made mappings in server-config.wsdd:
>
> <operation name="list" returnQName="pub:codes"
> returnType="pub:ArrayOfCodes" />
> <arrayMapping qname="pub:ArrayOfCodes"
> type="java:it.cineca.UID[]"
> innerType="pub:Code" />
> <typeMapping qname="pub:Code"
> type="java:it.cineca.UID"
> serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
> deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory" />
> <typeMapping qname="pub:CodeImpl"
>   type="java:it.cineca.mods.CodeImpl"
>   serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
>   deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory" />
>
> I created a simple client that sends the following payload:
>
> <?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"
> xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
> xmlns:ns4="http://example.com/service">
> <SOAP-ENV:Body>
>   <ns4:list/>
> </SOAP-ENV:Body>
> </SOAP-ENV:Envelope>
>
> I see, from my application logs, that my method is correctly invoked by
> Axis, but Axis replies to me just with HTTP/1.1 200 OK,
> without any SOAP envelope :-(
>
> I expect something like this:
> <?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>
>   <listResponse xmlns="http://example.com/service">
>    <codes xsi:type="pub:ArrayOfCodes">
>     <code xsi:type="pub:CodeImpl">
>      <value>100</value>
>      <lastUpdateDate>somedatetime</lastUpdateDate>
>     </code>
>     <code xsi:type="pub:CodeImpl">
>      <value>100</value>
>      <lastUpdateDate>anotherdatetime</lastUpdateDate>
>     </code>
>   </listResponse>
> </soapenv:Body>
> </soapenv:Envelope>
>
> What I'm wrong? I find strange that Axis doesn't return anything...
>
> Thank in advance.
>
> Bye,
> Davide Romanini
>
>