IGNITE-6485: Binary marshalling with writeReplace/readResolve fixed. This closes #2778.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/d7fbbd54 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/d7fbbd54 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/d7fbbd54 Branch: refs/heads/ignite-3478 Commit: d7fbbd546126252af45cb48a5d173a7a66ad9838 Parents: 9160d5e Author: Andrey Gura <[email protected]> Authored: Mon Oct 2 12:38:34 2017 +0300 Committer: devozerov <[email protected]> Committed: Mon Oct 2 12:38:34 2017 +0300 ---------------------------------------------------------------------- .../internal/binary/BinaryClassDescriptor.java | 4 +- .../ignite/internal/util/IgniteUtils.java | 43 ++++-- .../binary/BinaryMarshallerSelfTest.java | 136 +++++++++++++------ 3 files changed, 130 insertions(+), 53 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/d7fbbd54/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java index 4950a53..935211e 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java @@ -344,9 +344,9 @@ public class BinaryClassDescriptor { Method writeReplaceMthd; if (mode == BinaryWriteMode.BINARY || mode == BinaryWriteMode.OBJECT) { - readResolveMtd = U.findNonPublicMethod(cls, "readResolve"); + readResolveMtd = U.getNonPublicMethod(cls, "readResolve"); - writeReplaceMthd = U.findNonPublicMethod(cls, "writeReplace"); + writeReplaceMthd = U.getNonPublicMethod(cls, "writeReplace"); } else { readResolveMtd = null; http://git-wip-us.apache.org/repos/asf/ignite/blob/d7fbbd54/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java index 31b556d..bdcf87e 100755 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java @@ -9407,22 +9407,14 @@ public abstract class IgniteUtils { * @param cls The class to search, * @param name Name of the method. * @param paramTypes Method parameters. - * @return Method or {@code null} + * @return Method or {@code null}. */ @Nullable public static Method findNonPublicMethod(Class<?> cls, String name, Class<?>... paramTypes) { while (cls != null) { - try { - Method mtd = cls.getDeclaredMethod(name, paramTypes); + Method mtd = getNonPublicMethod(cls, name, paramTypes); - if (mtd.getReturnType() != void.class) { - mtd.setAccessible(true); - - return mtd; - } - } - catch (NoSuchMethodException ignored) { - // No-op. - } + if (mtd != null) + return mtd; cls = cls.getSuperclass(); } @@ -9431,6 +9423,33 @@ public abstract class IgniteUtils { } /** + * Gets a method from the class. + * + * Method.getMethod() does not return non-public method. + * + * @param cls Target class. + * @param name Name of the method. + * @param paramTypes Method parameters. + * @return Method or {@code null}. + */ + @Nullable public static Method getNonPublicMethod(Class<?> cls, String name, Class<?>... paramTypes) { + try { + Method mtd = cls.getDeclaredMethod(name, paramTypes); + + if (mtd.getReturnType() != void.class) { + mtd.setAccessible(true); + + return mtd; + } + } + catch (NoSuchMethodException ignored) { + // No-op. + } + + return null; + } + + /** * @param cls The class to search. * @param name Name of a field to get. * @return Field or {@code null}. http://git-wip-us.apache.org/repos/asf/ignite/blob/d7fbbd54/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java index 926b3c0..ef68cd1 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java @@ -938,6 +938,23 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest { } /** + * @throws Exception If failed. + */ + public void testWriteReplace() throws Exception { + BinaryMarshaller marsh = binaryMarshaller(Collections.singleton( + new BinaryTypeConfiguration(TestObject.class.getName()) + )); + + TestObject obj = new TestObject(); + + BinaryObject po = marshal(obj, marsh); + + assertEquals(obj, po.deserialize()); + + assertEquals(obj.val, ((BinaryObject)po.field("val")).deserialize()); + } + + /** * */ private static class EnclosingObj implements Serializable { @@ -2626,19 +2643,6 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest { } /** - * @throws Exception If ecxeption thrown. - */ - public void testDeclareReadResolveInParent() throws Exception { - BinaryMarshaller marsh = binaryMarshaller(Arrays.asList(new BinaryTypeConfiguration(ChildBinary.class.getName()))); - - BinaryObjectImpl binaryObj = marshal(new ChildBinary(), marsh); - - ChildBinary singleton = binaryObj.deserialize(); - - assertNotNull(singleton.s); - } - - /** * */ public void testDecimalFields() throws Exception { @@ -5117,13 +5121,6 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest { /** * */ - public static class ChildBinary extends ParentBinary { - - } - - /** - * - */ public static class SimpleEnclosingObject { /** */ private Object simpl; @@ -5180,25 +5177,6 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest { } /** - * - */ - private static class ParentBinary { - /** */ - public String s; - - /** - * Package only visibility!!!! - * - * @return Object. - */ - Object readResolve() { - s = "readResolve"; - - return this; - } - } - - /** * Class B for duplicate fields test. */ private static class DuplicateFieldsA { @@ -5517,4 +5495,84 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest { abstract boolean isSupported(); } + + /** */ + interface Intf { + /** */ + long value(); + } + + /** */ + static class TestObject { + /** Value. */ + Intf val = new IntfImpl(); + + /** {@inheritDoc} */ + @Override public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + + TestObject obj = (TestObject)o; + + return val.equals(obj.val); + } + } + + /** */ + static class IntfImpl extends Cls implements Intf { + /** {@inheritDoc} */ + @Override public long value() { + return longValue(); + } + } + + /** */ + static class Cls implements Serializable { + /** Value. */ + long val; + + /** */ + public long longValue() { + return val; + } + + /** {@inheritDoc} */ + @Override public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + + Cls cls = (Cls)o; + + return val == cls.val; + } + + /** */ + private Object writeReplace() { + return new SerializationProxy(this); + } + + /** */ + private static class SerializationProxy implements Serializable { + /** Value. */ + private final long val; + + /** */ + SerializationProxy(Cls a) { + val = a.longValue(); + } + + /** */ + private Object readResolve() { + Cls a = new Cls(); + + a.val = val; + + return a; + } + } + } } \ No newline at end of file
