RMI Serialization and Collections

Posted on 2002-05-09
Last Modified: 2013-12-29

     since serialization creates new instances of an object, making sense
     of a serialized Collection seems difficult.  i have a need to put
     things in Sets or Lists and later, "across the wire", compare them
     against other Sets, Lists, or Objects.  anyone have advice on a
     (hopefully simple) way to do this in general?  for specifics, consider
     the following two classes (simplified and abbreviated) and output:
     public class TestServerImpl extends UnicastRemoteObject implements
     TestServer, Serializable {

       // only used because Object doesn't implement Serializable...
       class SerialObject implements Serializable {}

       private SerialObject theObject;
       private Collection theSet;

       static public void main() {

         TestServer ts = new TestServerImpl()
       private TestServer() {
         theObject = new SerialObject();
         theSet = new HashSet();
       // methods promised in TestServer interface
       public Object getObject() { return theObject; }
       public Collection getSet() { return theSet; }
     public class Test {
       public static void main() {
         TestServer ts = (TestServer)
         Object aThing = ts.getObject();
         Collection aSet = ts.getSet();
         System.out.println("thing is :"+aThing);
         System.out.println("set is :"+aSet);
         System.out.println("set contains thing? "+aSet.contains(aThing));
     the output is what you'd expect, but not what you'd want.  something

     thing is :SerialObject@743399
     set is :[SerialObject@67b241]
     set contains thing? false

     i know readResolve() can be used to return an existing object instead
     of a new object from the deserialization process, but this seems an
     awfully bulky solution in general.  am i just way off base in my


Question by:dddexter
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
  • 2
  • +1

Expert Comment

ID: 6999889
Classes implementing Collection (and List) implements (or should implement, according the the spec)
Collection.contains(Object obj)
by iterating over the collection, calling
object.equals(obj) where object is the current object returned by the iterator.

So, by overriding equals(Object obj) from class Object, you can specify your own comparison routine
class Bla {
private int iVal = 5;
public int getIVal() {
return iVal;
public boolean equals(Object o) {
if (obj intanceof Bla && ((Bla) obj).getIVal() == this.getIVal()) {
return true;
} else {
return false;

Expert Comment

ID: 6999893
class Bla {
private int iVal = 5;
public int getIVal() {
return iVal;
public boolean equals(Object obj) {
if (obj intanceof Bla && ((Bla) obj).getIVal() == this.getIVal()) {
return true;
} else {
return false;

LVL 92

Expert Comment

ID: 7000161
The default implementation of equals() provided by Object simply returns true of the tow objects are the same instance. ie. a==b.
Which in this case they aren't.
If theObject was a String or an Integer for example you would get the desired result.
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!


Author Comment

ID: 7000526

i'm not convinced that implementing equals() (and hashCode()) is the way to go.  i received a similar response to the question on google, so perhaps i'm
just being beligerent....

BUT, suppose (as is the case in my app) that the objects
are mutable:
Mutable a = new Mutable(propertySetA);
Mutable b = new Mutable(propertySetB);
// a==b false.  a.equals(b) false.  aSet.contains(b) false.
// a==b false.  a.equals(b) true?  aSet.contains(b) true?
// a==b false.  a.equals(b) false? aSet.contains(a) false?

further, if there are no obvious fields that clearly
define equals(), one would need to do something like add
a uniqueId field as sort of a "key" to *every* class that
is to be serialized. this seems bulky and non-intuitive.
what do we do for classes provided by sun which may not
override equals()?  subclass or wrap each one in order
to serialize it?  seems messy.

on the server-side we can easily share references for any object w/o any extra coding...just assign a variable.
is there no way to, in general, deserialize the *same* object (a single reference)to two variables and compare
them as equal?  i'm beginning to doubt it, but it seems suspect.

thanks for your input,


Author Comment

ID: 7009238
Ok, I give.

guess my unfamiliarity w/ serialization was really the underlying problem.
i just couldn't get it through my thick skull that a single object serialized and
deserialized twice to two different references would appear as two new and
distinct objects.  period.  

options are to a)  implement equals() to make them "appear" to be the same
object (sort of) or b) implement readResolve().  readResolve() is probably
closer to what i was after, but to use it in a simple manner requires some
of the same hooks as implementing equals() (either an immutable object
or some sort of unique id field).  

in the end, i've resolved the problem by only passing objects once (which
is probably better) and doing the logic on the client side.

i *think* a solution for what i was after (although an overly complex one)
would be to :
1) implement writeObject() and readObject for every object to be sent
to the client.  they would perform default operation with the addition of
writing/reading the object's hashCode.  since the writeObject() is server
side, the hashCode would be that of the server-side object.
2) build a hashMap on the client that contains every object recieved
indexed by its *server-side* hashCode.
3) implement readResolve() for every object to be passed.  have it
check the local hasMap to see if the object has already been passed
and return that copy if so - otherwise add it.

still wouldn't work for a mutable object modified on the server between
serializations....but i'm not sure it should...


LVL 92

Accepted Solution

objects earned 200 total points
ID: 7009855
Doesn't that solution assume that hash code of evey object is unique?

Author Comment

ID: 7010011
check that,  you clearly can't use hashCode
because these aren't guarenteed to be unique.
you'd have to develop a good unique id for each


Expert Comment

ID: 7050632
I think the solution is to supply stable hashCode and equals for your own types.
You can build equals and hashCode according to the member class they have.

In your example you have to supply it to the SerialObject
for example:

public int hashCode() {
   //assuming HashSet suplly stable and good hash code even it  recreated
   return theSet.hashCode();

public boolean equals(Object obj) {
  if(obj instanceOf SerialObject) {
       //assuming the collection provide good equals method.
       return theSet.equals(((SerialObject)obj).getSet());
  } else {
       return false;

Author Comment

ID: 7051567
evidently, this has run its course for new ideas.  i think the idea of using something
like "an interface defining a good uniqeObjectId (as distinct from a hashCode)
to build a client object map which readResolve uses to ensure that objects are
only built on the client side a single time" is interesting, but i ain't pursuing it.

points are yours "objects".  by default i suppose.

LVL 92

Expert Comment

ID: 7052378
Ta :)

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article is the first of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article explains our test automation goals. Then rationale is given for the tools we use to a…
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
This video teaches viewers about errors in exception handling.
Suggested Courses

739 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question