From f8bd75d37ca12c5d49c1b628c33c0b45e2d082eb Mon Sep 17 00:00:00 2001 From: Thomas Neidhart Date: Mon, 28 Sep 2015 08:53:44 +0000 Subject: [PATCH] [COLLECTIONS-576] Fix de-serialization of MultiKey subclasses: hashcode was not re-calculated. Thanks to Stephan Roch. git-svn-id: https://svn.apache.org/repos/asf/commons/proper/collections/trunk@1705620 13f79535-47bb-0310-9956-ffa450edef68 --- src/changes/changes.xml | 3 ++ .../collections4/keyvalue/MultiKey.java | 2 +- .../collections4/keyvalue/MultiKeyTest.java | 38 +++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 196a16bbb..61ee47151 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -22,6 +22,9 @@ + + Subclasses of MultiKey did not re-calculate their hashcode after de-serialization. + Added set operations to "SetUtils": union, difference, intersection and disjunction. The operations return a view of the result that is backed by the input sets. diff --git a/src/main/java/org/apache/commons/collections4/keyvalue/MultiKey.java b/src/main/java/org/apache/commons/collections4/keyvalue/MultiKey.java index 794677c5c..2b08d8a73 100644 --- a/src/main/java/org/apache/commons/collections4/keyvalue/MultiKey.java +++ b/src/main/java/org/apache/commons/collections4/keyvalue/MultiKey.java @@ -274,7 +274,7 @@ public class MultiKey implements Serializable { * only stable for the same process). * @return the instance with recalculated hash code */ - private Object readResolve() { + protected Object readResolve() { calculateHashCode(keys); return this; } diff --git a/src/test/java/org/apache/commons/collections4/keyvalue/MultiKeyTest.java b/src/test/java/org/apache/commons/collections4/keyvalue/MultiKeyTest.java index 39f065939..51b130928 100644 --- a/src/test/java/org/apache/commons/collections4/keyvalue/MultiKeyTest.java +++ b/src/test/java/org/apache/commons/collections4/keyvalue/MultiKeyTest.java @@ -254,4 +254,42 @@ public class MultiKeyTest extends TestCase { final MultiKey mk2 = new MultiKey(ONE, sysKey); assertEquals(TWO, map2.get(mk2)); } + + static class DerivedMultiKey extends MultiKey { + + private static final long serialVersionUID = 1928896152249821416L; + + public DerivedMultiKey(T key1, T key2) { + super(key1, key2); + } + + public T getFirst() { + return getKey(0); + } + + public T getSecond() { + return getKey(1); + } + + } + + public void testEqualsAfterSerializationOfDerivedClass() throws IOException, ClassNotFoundException + { + final DerivedMultiKey mk = new DerivedMultiKey("A", "B"); + + // serialize + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + final ObjectOutputStream out = new ObjectOutputStream(baos); + out.writeObject(mk); + out.close(); + + // deserialize + final ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + final ObjectInputStream in = new ObjectInputStream(bais); + final DerivedMultiKey mk2 = (DerivedMultiKey)in.readObject(); + in.close(); + + assertEquals(mk.hashCode(), mk2.hashCode()); + } + }