You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by Paul Mietz Egli <pe...@lightsurf.com> on 2002/01/29 00:48:39 UTC

serialization bug in ArraySerializer (repost from axis-user)

Rich and company -

I posted a message to axis-user last week regarding what I think
is a bug in the org.apache.axis.encoding.ser.ArrayDeserializer
class.  I ran across this issue when testing a SOAP service that
returns an array of java.util.Properties objects.  Since these
objects implement java.util.Map and Axis reports green on interop
for arrays of Map, I thought that I didn't have to register a
custom deserializer.  It turns out that the default TypeRegistry
only has an entry for java.util.HashMap, not java.util.Map, so the
call to SerializationContext.getQNameForClass("java.util.Map") in
ArraySerializer returns null, which causes the call to die.

To get my server up and running, I added the following lines to
ArraySerializer:

  // line 148 in the 1/28/2002 nightly build
  String dims = "";
  while (componentType.isArray()) {
    componentType = componentType.getComponentType();
    dims += "[]";
  }

  /* -------------- start of new code -------------- */
  if (componentType.isAssignableFrom(java.util.Map.class)) {
    componentType = java.util.HashMap.class;
  }
  /* -------------- end of new code ---------------- */

  QName componentQName = context.getQNameForClass(componentType);

Now that I've gone back and looked at it again, I think I prefer
this fix:

  // line 148 in the 1/28/2002 nightly build
  String dims = "";
  while (componentType.isArray()) {
    componentType = componentType.getComponentType();
    dims += "[]";
  }

  QName componentQName = context.getQNameForClass(componentType);

  /* -------------- start of new code -------------- */
  if (componentQName == null) {
    Class interfaces[] = componentType.getInterfaces();
    if (interfaces != null) {
      for (int i=0; i < interfaces.length; i++) {
        componentQName = context.getQNameForClass(interfaces[i]);
        if (componentQName != null) {
          break;
        }
      }
    }
  }
  /* -------------- end of new code ---------------- */

  if (componentQName == null)
    throw new IOException(
      JavaUtils.getMessage("noType00", componentType.getName()));
  ...

The MapSerializer and MapDeserializer classes only use functions
in the Map interface, so they are appropriate for use with all
objects that implement Map, including my java.util.Properties
object.  At first glance, it would be better to replace HashMap
with Map in the TypeMappingRegistry, but I suspect that the entries
in that class are also used to find concrete classes to new up when
needed, and "new Map()" wouldn't go over very well.

If anyone has any questions about this modification, please drop me
an email.

p.