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.
Creating Instructional Tutorials  

For Any Use & On Any Platform

Contextual Guidance at the moment of need helps your employees/users adopt software o& achieve even the most complex tasks instantly. Boost knowledge retention, software adoption & employee engagement with easy solution.


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: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say 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

For beginner Java programmers or at least those new to the Eclipse IDE, the following tutorial will show some (four) ways in which you can import your Java projects to your Eclipse workbench. Introduction While learning Java can be done with…
Introduction Java can be integrated with native programs using an interface called JNI(Java Native Interface). Native programs are programs which can directly run on the processor. JNI is simply a naming and calling convention so that the JVM (Java…
Viewers will learn about the regular for loop in Java and how to use it. Definition: Break the for loop down into 3 parts: Syntax when using for loops: Example using a for loop:
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.

707 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