1 /* 2 * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 8246774 27 * @summary Basic tests for writeReplace 28 * @run testng WriteReplaceTest 29 * @run testng/othervm/java.security.policy=empty_security.policy WriteReplaceTest 30 */ 31 package test.java.io.Serializable.records; 32 33 import java.io.ByteArrayInputStream; 34 import java.io.ByteArrayOutputStream; 35 import java.io.IOException; 36 import java.io.ObjectInputStream; 37 import java.io.ObjectOutputStream; 38 import java.io.Serializable; 39 import org.testng.annotations.DataProvider; 40 import org.testng.annotations.Test; 41 import static java.lang.System.out; 42 import static org.testng.Assert.assertEquals; 43 44 public class WriteReplaceTest { 45 46 record R1 () implements Serializable { writeReplace()47 Object writeReplace() { return new Replacement(); } 48 49 private static class Replacement implements Serializable { readResolve()50 private Object readResolve() { return new R1(); } 51 } 52 } 53 54 record R2 (int x, int y) implements Serializable { writeReplace()55 Object writeReplace() { return new Ser(x, y); } 56 57 private static class Ser implements Serializable { 58 private final int x; 59 private final int y; Ser(int x, int y)60 Ser(int x, int y) { this.x = x; this.y = y; } readResolve()61 private Object readResolve() { return new R2(x, y); } 62 } 63 } 64 65 record R3 (R1 r1, R2 r2) implements Serializable { } 66 67 record R4 (long l) implements Serializable { writeReplace()68 Object writeReplace() { return new Replacement(l); } 69 70 static class Replacement implements Serializable { 71 long l; Replacement(long l)72 Replacement(long l) { this.l = l; } 73 } 74 } 75 76 @DataProvider(name = "recordObjects") recordObjects()77 public Object[][] recordObjects() { 78 return new Object[][] { 79 new Object[] { new R1(), R1.class }, 80 new Object[] { new R2(1, 2), R2.class }, 81 new Object[] { new R3(new R1(), new R2(3,4)), R3.class }, 82 new Object[] { new R4(4L), R4.Replacement.class }, 83 }; 84 } 85 86 @Test(dataProvider = "recordObjects") testSerialize(Object objectToSerialize, Class<?> expectedType)87 public void testSerialize(Object objectToSerialize, Class<?> expectedType) 88 throws Exception 89 { 90 out.println("\n---"); 91 out.println("serializing : " + objectToSerialize); 92 Object deserializedObj = serializeDeserialize(objectToSerialize); 93 out.println("deserialized: " + deserializedObj); 94 if (objectToSerialize.getClass().equals(expectedType)) 95 assertEquals(deserializedObj, objectToSerialize); 96 else 97 assertEquals(deserializedObj.getClass(), expectedType); 98 } 99 100 // -- null replacement 101 102 record R10 () implements Serializable { writeReplace()103 Object writeReplace() { return null; } 104 } 105 106 @Test testNull()107 public void testNull() throws Exception { 108 out.println("\n---"); 109 Object objectToSerialize = new R10(); 110 out.println("serializing : " + objectToSerialize); 111 Object deserializedObj = serializeDeserialize(objectToSerialize); 112 out.println("deserialized: " + deserializedObj); 113 assertEquals(deserializedObj, null); 114 } 115 116 // --- infra 117 serialize(T obj)118 static <T> byte[] serialize(T obj) throws IOException { 119 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 120 ObjectOutputStream oos = new ObjectOutputStream(baos); 121 oos.writeObject(obj); 122 oos.close(); 123 return baos.toByteArray(); 124 } 125 126 @SuppressWarnings("unchecked") deserialize(byte[] streamBytes)127 static <T> T deserialize(byte[] streamBytes) 128 throws IOException, ClassNotFoundException 129 { 130 ByteArrayInputStream bais = new ByteArrayInputStream(streamBytes); 131 ObjectInputStream ois = new ObjectInputStream(bais); 132 return (T) ois.readObject(); 133 } 134 serializeDeserialize(T obj)135 static <T> T serializeDeserialize(T obj) 136 throws IOException, ClassNotFoundException 137 { 138 return deserialize(serialize(obj)); 139 } 140 } 141