Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4890211
Votes 0
Synopsis (coll) Collections.ReverseOrder.equals method is lacking
Category java:classes_util
Reported Against 1.4.2
Release Fixed mustang(b71)
State 10-Fix Delivered, bug
Priority: 4-Low
Related Bugs 6372554 , 6483125
Submit Date 14-JUL-2003
Description


FULL PRODUCT VERSION :
java version "1.4.0_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0_01-b03)
Java HotSpot(TM) Client VM (build 1.4.0_01-b03, mixed mode)

also:

java version "1.3.1_04"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1_04-b02)
Java HotSpot(TM) Client VM (build 1.3.1_04-b02, mixed mode)

FULL OPERATING SYSTEM VERSION :

glibc: glibc-2.2.5-42
Kernal: Linux 2.4.18-18-7.x #1 Wed Nov 13 20:29:30 EST 2002
i686
distro:  customer -release

ADDITIONAL OPERATING SYSTEMS :

(seems like a pure java issue to me)

A DESCRIPTION OF THE PROBLEM :
Collections.reverseOrder().equals(deserialize(serialize
(Collections.reverseOrder()) returns false.

The JavaDocs for java.util.Comparator.equals suggests (but
doesn't strictly require):

"[T]his method can return true only if the specified Object
is also a comparator and it imposes the same ordering as
this comparator.  Thus comp1.equals(comp2) implies that sgn
(comp1.compare(o1,o2)) == sgn(comp2.compare(o1,o2)) for
every  customer  reference o1 and o2."

The java.util.Collections.reverseOrder method returns a
Comparator that could readily support this "soft contract",
but doesn't when serialized, deserialized and compared back
to itself.

See the sample unit test below.

Overriding Object.equals would allow
Collections.ReverseComparator to support this case as
well.  Something like this:

public boolean equals(Object that) {
  return (that == this ||
         that instanceof Collections.ReverseComparator);
}

should suffice, since Collections.ReverseComparator is
final (although I suppose it is still possible for
instanceof to fail if "this" and "that" were loaded via
different ClassLoaders).

That Comparator suggests implementations should be
Serializable, and that ReverseComparator is itself
Serializable suggests that this problem isn't as obscure as
it might at first seem.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compare two distinct instances of
Collections.ReverseComparator and compare them using the
equals method.

One way to get two distinct instances is to serialize and
then deserialize a single instance.  See sample code below.

EXPECTED VERSUS ACTUAL BEHAVIOR :
Collections.reverseOrder().equals(deserialize(serialize
(Collections.reverseOrder()) should return true.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.util.Collections;
import java.util.Comparator;
import junit.framework.*;

public class TestReverseOrder extends TestCase {
  public TestReverseOrder(String name) {
    super(name);
  }

  public static Test suite() {
    return new TestSuite(TestReverseOrder.class);
  }
    
  public void testEqualsDeserializedInstance() throws Exception {
    // obtain an instance of Collections.ReverseOrder
    Comparator comp1 = Collections.reverseOrder();

    // note that it is equal to itself
    assertTrue( "equals should be reflexive", comp1.equals(comp1) );
    // or assertEquals(comp1,comp1);

    // serialize it
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    ObjectOutputStream out = new ObjectOutputStream(buffer);
    out.writeObject(comp1);

    // deserialize it
    ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream
(buffer.toByteArray()))
    Comparator comp2 = (Comparator)(in.readObject());

    // note that comp1 is not equal to its deserialized clone
    assertEquals( "should equal deserialized clone", comp1.equals(comp2) );
    // or assertEquals(comp1,comp2);
  }
}
---------- END SOURCE ----------
(Incident Review ID: 179731) 
======================================================================
Posted Date : 2006-01-17 21:42:44.0
Work Around
N/A
Evaluation
The simpler fix would be to simply have serialization followed
by de-serialization yield the same identical object, as is done
by other "singleton"s in Collections.java.
Posted Date : 2006-01-17 21:42:44.0
Comments
  
  Include a link with my name & email   


PLEASE NOTE: JDK6 is formerly known as Project Mustang