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 Aaron Hamid <ar...@cornell.edu> on 2004/01/23 17:58:49 UTC

Dynamic type serialization

Hi all,

   Dims, Tom, Glen, I am {aaron} from Freenode.

Anyway, I am having problems implementing "dynamic type" serialization 
  under Axis.  I can probably best explain what I mean with an example:

Say we have some sort of opaque complex type as input and output 
messages to some soap call.  Let's also say I'm doing dynamic 
invocation.  That means I do not have "proper" 
serialization/deserialization stubs for the aforementioned opaque 
input/output types.  Is all lost?  No.  If I take a Map object, I can 
make a best-effort to serialize key/value pairs as elements in the 
opaque type.  Of course this is not going to be accurate, and without 
recursion will only work for one level of nesting, however, it is 
probably going to still catch a majority of cases (at least in my 
environment).

The problem is, that serialization and deserialization factories and 
TypeDescs, are mapped on Class.  This renders the above scheme 
impossible without some sort of ThreadLocal hacks.

Let's examine.  Let's say I create a new custom "bean" DynamicType. 
DynamicType, will take a Map object, inspect the map for key/value 
pairs, and expose those key/value pairs as ElementDescs in the 
TypeDesc it holds.  We will have to create a TypeDesc subclass that 
can store an explicitly constructed BeanPropertyDescriptor array, as 
the default TypeDesc implementation does implicit bean introspection 
(which of course will produce the "wrong thing" when introspecting a 
Map - it will just produce the interface of the Map object itself).

That is straightforward enough.  Since BeanSerializerFactory 
dynamically looks up the TypeDesc from the class it is passed, we must 
subclass BeanSerializerFactory (let's call it 
DynamicSerializerFactory) so that it takes a concrete instance of our 
aforementioned DynamicType, initialized with the Map object. 
Everything looks good so far - our DynamicSerializer factory will 
behave like a BeanSerializerFactory which produces Serializers for 
beans whose interface is that provided by the DynamicTypeDesc and 
explicit properties inspected in the Map.  Sounds good.

But now comes the catch.  We have to register this factory based on 
the _CLASS_ of input type - DynamicType.  However, if we register this 
specific factory instance for ALL DynamicType classes, we will 
inevitably produce the wrong interface at some point if this mapping 
gets overwritten with one initialized with a different concrete Map 
object.

The only solution I see is to go ahead and register our 
DynamicSerializerFactory, however, instead of keeping a member 
instance of DynamicTypeDesc, keep a ThreadLocal instance containing a 
DynamicTypeDesc, so that when we are called somewhere down the line in 
the invoke process we will produce the correct serializer for the 
interface provided by the correct DynamicType for THIS SPECIFIC 
invocation.

HOWEVER this is a big hack, and relies on the assumption that the 
invocation dispatching thread is the SAME THREAD in which we map the 
factory.

So my question is:

1) does this make sense
2) is there any way around it, or better way to implement what I want 
that I haven't found
3) does, in fact, the invocation get executed by the same thread as 
the caller? (I /think/ so, but I don't want to assume this, as all 
sorts of things like thread pools, etc., could potentially be coming 
into play)