I've found what I think is a bug in the RPC deserialization code for
handling HashSet and HashMap in GWT 1.5.3 (though I believe it applies
to trunk as well). The symptoms I had initially were that I sent an
object tree to the client, and a HashSet that had 2 elements on the
server only had 1 by the time it got to the client.

When deserializing, an instance is created, stored in a map so repeated
references can use the same instance, and then the fields of the
instance are  deserialized.  If you have an object tree where A contains
a reference to something that has a reference to B, and B contains
something that has a reference to a HashSet that contains both A and B,
then when deserializing the set, both A and B may only be partially
constructed (depending on the order in which the fields and instances
are deserialized). This would be ok except that HashSet deserialization
is done by Collection_CustomFieldSerializerBase which ends up calling
HashSet.add(Object) to reconstitute the set, and that in turn calls
equals() and hashCode() on the object being added in.

This gives rise to two possible errors:
(1) Depending on how the equals() method on A and B is implemented and
on the order in which the fields are deserialized, A.equals(B) may be
true at the time that A and B are added to the set. However, A.equals(B)
could later evaluate to false once the whole deserialization has
completed. This would mean the set is missing one of the objects, since
HashSet.add() thinks they are the same.

(2) When adding an object to a HashSet or HashMap during
deserialization, if the object being added is partially constructed,
then the hashCode() method may return a different value as it is added
to the set from what it does when deserialization is complete. This
could lead to occasional data-driven bugs that are very hard to track down.

Have I got this right? Is this a bug (or perhaps a known limitation)?

In my case, I have been able to work around this by creating a custom
field serializer that chooses the order in which fields are written out
so that partially constructed objects will still behave properly in a
HashSet/HashMap.

Paul


--~--~---------~--~----~------------~-------~--~----~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~----------~----~----~----~------~----~------~--~---

Reply via email to