1 /* 2 * Copyright (c) 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 8238763 8246774 27 * @summary ObjectInputStream readUnshared method handling of Records 28 * @run testng UnsharedTest 29 */ 30 package test.java.io.Serializable.records; 31 32 import java.io.ByteArrayInputStream; 33 import java.io.ByteArrayOutputStream; 34 import java.io.IOException; 35 import java.io.InvalidObjectException; 36 import java.io.ObjectInputStream; 37 import java.io.ObjectOutputStream; 38 import java.io.Serializable; 39 import org.testng.annotations.Test; 40 import static org.testng.Assert.assertEquals; 41 import static org.testng.Assert.assertTrue; 42 import static org.testng.Assert.expectThrows; 43 44 /** 45 * Tests OOS::writeUnshared and OIS::readUnshared to verify that records 46 * are correctly unshared in the stream as appropriate. 47 */ 48 public class UnsharedTest { 49 50 record Foo(int x) implements Serializable { } 51 52 static final Class<InvalidObjectException> IOE = InvalidObjectException.class; 53 54 @Test testReadUnshared()55 public void testReadUnshared() throws Exception { 56 var foo = new Foo(6); 57 { // shared - sanity to ensure the second foo is a ref 58 var byteStream = serialize(foo, foo); 59 var foo1 = (Foo) deserializeOne(byteStream); 60 assertEquals(foo1.x, foo.x); 61 var foo2 = (Foo) deserializeOne(byteStream); 62 assertEquals(foo2.x, foo.x); 63 assertTrue(foo2 == foo1); 64 } 65 { // unshared 66 var byteStream = serialize(foo, foo); 67 var foo1 = (Foo) deserializeOneUnshared(byteStream); 68 assertEquals(foo1.x, foo.x); 69 var expected = expectThrows(IOE, () -> deserializeOne(byteStream)); 70 assertTrue(expected.getMessage().contains("cannot read back reference to unshared object")); 71 } 72 } 73 74 @Test testWriteUnshared()75 public void testWriteUnshared() throws Exception { 76 var foo = new Foo(7); 77 { // shared - sanity to ensure the second foo is NOT a ref 78 var byteStream = serializeUnshared(foo, foo); 79 var foo1 = (Foo) deserializeOne(byteStream); 80 assertEquals(foo1.x, foo.x); 81 var foo2 = (Foo) deserializeOne(byteStream); 82 assertEquals(foo2.x, foo.x); 83 assertTrue(foo2 != foo1); 84 } 85 { // unshared 86 var byteStream = serializeUnshared(foo, foo); 87 var foo1 = (Foo) deserializeOneUnshared(byteStream); 88 assertEquals(foo1.x, foo.x); 89 var foo2 = (Foo) deserializeOneUnshared(byteStream); 90 assertEquals(foo2.x, foo.x); 91 assertTrue(foo2 != foo1); 92 } 93 } 94 95 // --- 96 serialize(Object... objs)97 static ObjectInputStream serialize(Object... objs) throws IOException { 98 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 99 ObjectOutputStream oos = new ObjectOutputStream(baos); 100 for (Object obj : objs) 101 oos.writeObject(obj); 102 oos.close(); 103 ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); 104 return new ObjectInputStream(bais); 105 } 106 serializeUnshared(Object... objs)107 static ObjectInputStream serializeUnshared(Object... objs) throws IOException { 108 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 109 ObjectOutputStream oos = new ObjectOutputStream(baos); 110 for (Object obj : objs) 111 oos.writeUnshared(obj); 112 oos.close(); 113 ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); 114 return new ObjectInputStream(bais); 115 } 116 117 @SuppressWarnings("unchecked") deserializeOne(ObjectInputStream ois)118 static Object deserializeOne(ObjectInputStream ois) 119 throws IOException, ClassNotFoundException 120 { 121 return ois.readObject(); 122 } 123 124 @SuppressWarnings("unchecked") deserializeOneUnshared(ObjectInputStream ois)125 static Object deserializeOneUnshared(ObjectInputStream ois) 126 throws IOException, ClassNotFoundException 127 { 128 return ois.readUnshared(); 129 } 130 } 131