1 /* 2 * Copyright (c) 2015, 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 import java.io.ByteArrayInputStream; 25 import java.io.ByteArrayOutputStream; 26 import java.io.IOException; 27 import java.io.ObjectInputStream; 28 import java.io.ObjectOutputStream; 29 import java.util.Base64; 30 import java.util.Properties; 31 32 /** 33 * @test 34 * @bug 8029891 35 * @summary tests the compatibility of Properties serial form 36 * @run main PropertiesSerialization read 37 * @author bchristi 38 * 39 * To update this test in case the serial form of Properties changes, run this 40 * test with the 'write' flag, and copy the resulting output back into this 41 * file, replacing the existing String declaration(s). 42 */ 43 public class PropertiesSerialization { 44 private static final Properties TEST_PROPS; 45 static { 46 TEST_PROPS = new Properties(); 47 TEST_PROPS.setProperty("one", "two"); 48 TEST_PROPS.setProperty("buckle", "shoe"); 49 TEST_PROPS.setProperty("three", "four"); 50 TEST_PROPS.setProperty("shut", "door"); 51 } 52 53 /** 54 * Base64 encoded string for Properties object 55 * Java version: 1.8.0 56 **/ 57 private static final String TEST_SER_BASE64 = 58 "rO0ABXNyABRqYXZhLnV0aWwuUHJvcGVydGllczkS0HpwNj6YAgABTAAIZGVmYXVs" 59 + "dHN0ABZMamF2YS91dGlsL1Byb3BlcnRpZXM7eHIAE2phdmEudXRpbC5IYXNodGFi" 60 + "bGUTuw8lIUrkuAMAAkYACmxvYWRGYWN0b3JJAAl0aHJlc2hvbGR4cD9AAAAAAAAI" 61 + "dwgAAAALAAAABHQAA29uZXQAA3R3b3QABHNodXR0AARkb29ydAAGYnVja2xldAAE" 62 + "c2hvZXQABXRocmVldAAEZm91cnhw"; 63 64 public static void main(String[] args) throws IOException, 65 ClassNotFoundException { 66 if (args.length == 0) { 67 System.err.println("Run with 'read' or 'write'"); 68 System.err.println(" read mode: normal test mode."); 69 System.err.println(" Confirms that serial stream can"); 70 System.err.println(" be deserialized as expected."); 71 System.err.println(" write mode: meant for updating the test,"); 72 System.err.println(" should the serial form change."); 73 System.err.println(" Test output should be pasted"); 74 System.err.println(" back into the test source."); 75 return; 76 } 77 78 Properties deserializedObject; 79 if ("read".equals(args[0])) { 80 ByteArrayInputStream bais = new 81 ByteArrayInputStream(Base64.getDecoder().decode(TEST_SER_BASE64)); 82 try (ObjectInputStream ois = new ObjectInputStream(bais)) { 83 deserializedObject = (Properties) ois.readObject(); 84 } 85 if (!TEST_PROPS.equals(deserializedObject)) { 86 throw new RuntimeException("deserializedObject not equals()"); 87 } 88 System.out.println("Test passed"); 89 } else if ("write".equals(args[0])) { 90 System.out.println("\nTo update the test, paste the following back " 91 + "into the test code:\n"); 92 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 93 ObjectOutputStream oos = new ObjectOutputStream(baos); 94 oos.writeObject(TEST_PROPS); 95 oos.flush(); 96 oos.close(); 97 98 byte[] byteArray = baos.toByteArray(); 99 // Check that the Properties deserializes correctly 100 ByteArrayInputStream bais = new ByteArrayInputStream(byteArray); 101 ObjectInputStream ois = new ObjectInputStream(bais); 102 Properties deser = (Properties)ois.readObject(); 103 if (!TEST_PROPS.equals(deser)) { 104 throw new RuntimeException("write: Deserialized != original"); 105 } 106 107 // Now get a Base64 string representation of the serialized bytes. 108 final String base64 = Base64.getEncoder().encodeToString(byteArray); 109 // Check that we can deserialize the Base64 string we just computed. 110 ByteArrayInputStream bais2 = 111 new ByteArrayInputStream(Base64.getDecoder().decode(base64)); 112 ObjectInputStream ois2 = new ObjectInputStream(bais2); 113 Properties deser2 = (Properties)ois2.readObject(); 114 if (!TEST_PROPS.equals(deser2)) { 115 throw new RuntimeException("write: Deserialized base64 != " 116 + "original"); 117 } 118 System.out.println(dumpBase64SerialStream(base64)); 119 } 120 } 121 122 private static final String INDENT = " "; 123 /* Based on: 124 * java/util/logging/HigherResolutionTimeStamps/SerializeLogRecored.java 125 */ 126 private static String dumpBase64SerialStream(String base64) { 127 // Generates the Java Pseudo code that can be cut & pasted into 128 // this test (see Jdk8SerializedLog and Jdk9SerializedLog below) 129 final StringBuilder sb = new StringBuilder(); 130 sb.append(INDENT).append(" /**").append('\n'); 131 sb.append(INDENT).append(" * Base64 encoded string for Properties object\n"); 132 sb.append(INDENT).append(" * Java version: ").append(System.getProperty("java.version")).append('\n'); 133 sb.append(INDENT).append(" **/").append('\n'); 134 sb.append(INDENT).append(" private static final String TEST_SER_BASE64 = ").append("\n").append(INDENT).append(" "); 135 final int last = base64.length() - 1; 136 for (int i=0; i<base64.length();i++) { 137 if (i%64 == 0) sb.append("\""); 138 sb.append(base64.charAt(i)); 139 if (i%64 == 63 || i == last) { 140 sb.append("\""); 141 if (i == last) sb.append(";\n"); 142 else sb.append("\n").append(INDENT).append(" + "); 143 } 144 } 145 return sb.toString(); 146 } 147 }