users@jax-rpc.java.net

Use of derived classes in JAX-RPC methods

From: Kim Topley <kt_at_TOPLEY.DEMON.CO.UK>
Date: Tue, 29 Oct 2002 08:34:00 -0700

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