Hi,

The hessian java code for deserialization (as of 3.0.20 latest and greatest 
version) appears to have a bug.

In java, it's possible to create the following object:

                        Serializable serial[] = new Serializable[2];
                        serial[0] = new String("hello");
                        serial[1] = new Long(2);

Both types implement serializable interface.

If I feed this object to the writeObject using:

                        hessianOut.writeObject(serial);

the following gets written to the fileoutputstream (control chars removed 
for clarity):

Vt [java.io.Serializablel   S helloS byez

Essentially I get a list (V) of Serializable interfaces which are marked as 
strings (S).


When I deserialize this file, the hessian code uses:

  public Object readList(AbstractHessianInput in, int length)

located in com.caucho.hessian.io.ArrayDeserializer.

The following gets invoked because the code assumes that the component type 
(Serializable) is known from the parsing of the data:

      if (_componentType != null) {
        for (int i = 0; i < data.length; i++)
          data[i] = in.readObject(_componentType);
      }

causing the following to be invoked:
      reader = _serializerFactory.getObjectDeserializer(type);

Getting a deserializer on an interface throws an exception as the 
instantiate method later on calls the constructor for the object type (null 
for an interface.)

Of course, this problem happens with any based interface type that is stored 
in an Array or a List and de/serialized as above.

Suggestion for fixing this issue: When an interface is given in an 
list/array, don't specify the type.

in public Object readList(AbstractHessianInput in, int length) located in 
class ArrayDeserializer

in the array case, replace:

        for (int i = 0; i < data.length; i++)
          data[i] = in.readObject(_componentType);

with:

        for (int i = 0; i < data.length; i++)
          data[i] = 
in.readObject(_componentType.isInterface()?Object.class:_componentType);

in the list case, replace:

        while (! in.isEnd())
          list.add(in.readObject(_componentType));

with:

        while (! in.isEnd())
          
list.add(in.readObject(_componentType.isInterface()?Object.class:_componentType));

Substituting the type when an interface to the object type, will not 
instantiate this type, as the code defaults to the generic readObject 
without any type specified.

Workaround

My current workaround is to pass a list of objects when I serialize my 
original array of interfaces.

                        Serializable serial[] = new Serializable[2];
                        serial[0] = new String("hello");
                        serial[1] = new Long(2);

                        List list = Arrays.asList(serial);


Any other ideas?

Thanks!

LdS

_________________________________________________________________
Get in the mood for Valentine's Day. View photos, recipes and more on your 
Live.com page. 
http://www.live.com/?addTemplate=ValentinesDay&ocid=T001MSN30A0701



_______________________________________________
hessian-interest mailing list
[email protected]
http://maillist.caucho.com/mailman/listinfo/hessian-interest

Reply via email to