You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "Thomas Neidhart (JIRA)" <ji...@apache.org> on 2015/11/27 22:12:13 UTC
[jira] [Closed] (COLLECTIONS-576) MultiKey subclassing has
deserialization problem since COLLECTIONS-266: either declare protected
readResolve() or MultiKey must be final
[ https://issues.apache.org/jira/browse/COLLECTIONS-576?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Thomas Neidhart closed COLLECTIONS-576.
---------------------------------------
> MultiKey subclassing has deserialization problem since COLLECTIONS-266: either declare protected readResolve() or MultiKey must be final
> ----------------------------------------------------------------------------------------------------------------------------------------
>
> Key: COLLECTIONS-576
> URL: https://issues.apache.org/jira/browse/COLLECTIONS-576
> Project: Commons Collections
> Issue Type: Bug
> Components: KeyValue
> Affects Versions: 4.0
> Reporter: Stephan Roch
> Fix For: 4.1
>
>
> MultiKey from collections 4 provides a transient hashCode and a *private* readResolve to resolve COLLECTIONS-266: Issue with MultiKey when serialized/deserialized via RMI.
> Unfortunately the solution does not work in case of *subclassing*: readResolve in MultiKey should be declared *protected* readResolve() to be called during deserialization of the subclass. Otherwise MultiKey must be final to avoid such subclassing.
> *Testcase*:
> {code:java|title=MultiKeySerializationTest.java}
> package de.ivu.test.common.collections4;
> import static org.junit.Assert.assertEquals;
> import java.io.ByteArrayInputStream;
> import java.io.ByteArrayOutputStream;
> import java.io.IOException;
> import java.io.ObjectInputStream;
> import java.io.ObjectOutputStream;
> import org.apache.commons.collections4.keyvalue.MultiKey;
> import org.junit.Test;
> public class MultiKeySerializationTest {
> @Test
> @SuppressWarnings("unchecked")
> public void testReadResolveEqualHashCode()
> throws IOException, ClassNotFoundException {
> class MultiKey2<A, B>
> extends MultiKey {
> private static final long serialVersionUID = 1928896152249821416L;
> public MultiKey2(A key1, B key2) {
> super(key1, key2);
> }
> public A getFirst() {
> return (A) getKey(0);
> }
> public B getSecond() {
> return (B) getKey(1);
> }
>
> // FIXME: MultiKey should either declare protected readResolve() or must be final.
> }
> MultiKey2<String, String> one = new MultiKey2<>("bla", "blub");
> System.out.println(one.hashCode());
> ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
> ObjectOutputStream out = new ObjectOutputStream(byteOut);
> out.writeObject(one);
> out.close();
> byte[] serialized = byteOut.toByteArray();
> ByteArrayInputStream byteIn = new ByteArrayInputStream(serialized);
> ObjectInputStream in = new ObjectInputStream(byteIn);
> MultiKey2<String, String> two = (MultiKey2<String, String>) in.readObject();
> System.out.println(two.hashCode());
> assertEquals("hashCode must be equal - please check for protected readResolve in MultiKey*", one.hashCode(),
> two.hashCode());
> }
> }
> {code}
> *Fix:*
> {code:java|title=MultiKey.java}
> @@ -274,7 +274,7 @@
> * only stable for the same process).
> * @return the instance with recalculated hash code
> */
> - private Object readResolve() {
> + protected Object readResolve() {
> calculateHashCode(keys);
> return this;
> }
> {code}
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)