[ 
https://issues.apache.org/jira/browse/COLLECTIONS-576?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Thomas Neidhart resolved COLLECTIONS-576.
-----------------------------------------
       Resolution: Fixed
    Fix Version/s: 4.1

Fixed in r1705620.

Thanks for the report and testcase.

> 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)

Reply via email to