users@jax-rpc.java.net

Re: Use of derived classes in JAX-RPC methods

From: Doug Kohlert <doug.kohlert_at_sun.com>
Date: Mon, 04 Nov 2002 16:21:27 -0800

Kim, this is a bug in the PolymorphicArraySerializer in the reference
implementation. This will be fixed in the next release of the JWSDP.

Thank you for letting us know about it.

Kim Topley wrote:
> Thank you for confirming that. Maybe you could help me with
> another issue in the same area.
>
> Suppose I defined a method that returns a HashMap in which the
> values are of type String[]. In order for serialization to work,
> I need to add java.lang.String[] to the additionalTypes list and
> use the usual model trick to get wsdeploy to recognize them.
> Having done this, both the client and server ends have a serializer
> for ArrayOfstring. This looks good. Further, the type mapping
> registry at both ends gets set up with a mapping to this serializer
> for Java type String[] and XML type ArrayofString.
>
> However, when I call this method, I get an error on the client side
> during deserialization -- the client deserialization happens upon
> an <item> element, but it expects to see an <element> element. This
> <item> element is inside the multi-ref serialization of the String[]
> object, which looks a bit like this:
>
> <ns0:ArrayOfstring xsi:type="enc:Array" ......>
> <item xsi:type="xsd:string">First in array</item>
>
> </ns0:ArrayOfstring>
>
> etc (from memory, so this may not be 100% correct).
>
> What seems to happen is this:
>
> 1. On the server side, a serializer for Java type String[] is required
> during serialization of the HashMap. This finds the one for
> ArrayOfstring,
> so the array is serialized as shown above, which looks correct to me.
>
> 2. On the client side, while deserializing the value in the HashMap,
> the code looks not at the element name (ArrayOfstring), but at the
> type -- enc:Array. This results in it using the polymorphic array
> deserializer (is I think the correct name) instead of the registered
> deserializer ArrayOfstring. Unfortunately, this deserializer expects
> to see nested <element> elements, not nested <item> elements.
>
> As a result of this, I can't see how to handle cases where I need to
> transfer a String[] (and it probably applies to other array types as
> well) unless the type is explicitly called out in the method signature.
> Is this a known issue, or am I doing something wrong?
>
> Regards
> Kim Topley
> Keyboard Edge Limited
>
>
>
> Doug Kohlert wrote:
>
>>Kim, your observations are correct and this is the intended behavior.
>>We took this stance for strictly a performance point of view as it takes
>>extra time at runtime to determine what is being serialized/deserialized
>>etc. So you are correct that you should create an AbstractValueType to
>>achieve the desired results.
>>
>>Thank you for your interest in JAXRPC.
>>
>>Kim Topley wrote:
>>
>>>Suppose I define an endpoint that uses two value types:
>>>
>>>BaseValueType - a value type acting as a base class, which is not abstract.
>>>DerivedValueType - a value type derived from BaseValueType.
>>>
>>>Suppose also that the endpoint includes the following methods:
>>>
>>> public BaseValueType transform(BaseValueType type)
>>> throws RemoteException;
>>> public HashMap geValueTypes() throws RemoteException;
>>>
>>>The first method accepts a BaseValueType object and returns it after
>>>making some changes. The second returns a HashMap in which all instances
>>>of BaseValueType appear as values. Any and all instances of BaseValueType
>>>could, of course, be instances of DerivedValueType.
>>>
>>>In order to deploy and run this service, the necessary additionalTypes
>>>element for DerivedValueType is added to config.xml and the endpoint
>>>element in the jaxrpc-ri.xml file refers to a model file, so that a
>>>serializer/deserializer for ExtendedValueType is created and registered
>>>at both the client and server ends.
>>>
>>>Here's the problem. If the client calls the transform() method and sends
>>>a DerivedValueType, it actually gets serialized as a BaseValueType. The
>>>same would happen at the server end. However, if the server includes
>>>DerivedValueTypes in the HashMap it returns from getValueType(), then this
>>>is serialized properly and the client will get the right type.
>>>
>>>It seems that the following is true:
>>>
>>>1. If the argument or return value is Object, an abstract class or an
>>> interface (that also look like valid value types), or if the object
>>> is in a collection, then the serialization choice is made at run-time,
>>> as it would have to be.
>>>2. If, however, the method signature involves concrete types, then the
>>> choice of serialization is made at compile time.
>>>
>>>In other words, to get the expected result, I would have to change the
>>>signature of the transform() class to
>>>
>>> public Object transform(Object o)
>>>
>>>or introduce an abstract base class:
>>>
>>> public AbstractValueType transform(AbstractValueType o)
>>>
>>>and then derive BaseValueType from it.
>>>
>>>Is this correct? And is it intended, or just a feature of the JAX-RPC
>>>reference implementation.
>>>
>>>Thanks in advance
>>>Kim Topley
>>>Keyboard Edge Limited
>>
>>--
>>Doug Kohlert
>>Java Software Division
>>Sun Microsystems, Inc.
>>phone: 503 345-9806
>


-- 
Doug Kohlert
Java Software Division
Sun Microsystems, Inc.
phone: 503 345-9806