1 /*
   2  * Copyright (c) 1999, 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 /* @test
  25  * @bug 4214888
  26  * @clean CheckModifiers TestClass1 TestClass2
  27  * @build CheckModifiers
  28  * @run main CheckModifiers
  29  * @summary Make sure that serialpersistentFields data member is used to
  30  *          represent tyhe serializable fields only if it has the modfiers
  31  *          static, final, private and the type is ObjectStreamField.
  32  *          No need to check for static, as ObjectStreamField class is not
  33  *          serializable.
  34  *
  35  */
  36 
  37 import java.io.*;
  38 class TestClass1 implements Serializable {
  39     // Missing the "final" modifier
  40     private static ObjectStreamField[] serialPersistentFields = {
  41         new ObjectStreamField("field1", Integer.class),
  42         new ObjectStreamField("field2", Double.TYPE),
  43     };
  44 
  45     Integer field1;
  46     double field2;
  47     int field3;
  48     String field4;
  49 
  50     public TestClass1(Integer f1, double f2, int f3, String f4) {
  51         field1 = f1;
  52         field2 = f2;
  53         field3 = f3;
  54         field4 = f4;
  55     }
  56 
  57     private void readObject(ObjectInputStream ois)
  58         throws IOException, ClassNotFoundException {
  59         ObjectInputStream.GetField pfields = ois.readFields();
  60 
  61         field1 = (Integer) pfields.get("field1", new Integer(100));
  62         field2 = pfields.get("field2", 99.99);
  63 
  64         /* These fields must be present in the stream */
  65         try {
  66             field3 = pfields.get("field3", 99);
  67             System.out.println("Passes test 1a");
  68         } catch(IllegalArgumentException e) {
  69             throw new Error("data field: field3 not in the persistent stream");
  70         }
  71         try {
  72             field4 = (String) pfields.get("field4", "Default string");
  73             System.out.println("Passes test 1b");
  74         } catch(IllegalArgumentException e) {
  75             throw new Error("data field: field4 not in the persistent stream");
  76         }
  77     }
  78 };
  79 
  80 
  81 class TestClass2 implements Serializable {
  82     // public instead of private
  83     public static final ObjectStreamField[] serialPersistentFields = {
  84         new ObjectStreamField("field1", Integer.class),
  85         new ObjectStreamField("field2", Double.TYPE),
  86     };
  87 
  88     Integer field1;
  89     double field2;
  90     int field3;
  91     String field4;
  92 
  93     public TestClass2(Integer f1, double f2, int f3, String f4) {
  94         field1 = f1;
  95         field2 = f2;
  96         field3 = f3;
  97         field4 = f4;
  98     }
  99 
 100     private void readObject(ObjectInputStream ois)
 101         throws IOException, ClassNotFoundException {
 102         ObjectInputStream.GetField pfields = ois.readFields();
 103 
 104         field1 = (Integer) pfields.get("field1", new Integer(100));
 105         field2 = pfields.get("field2", 99.99);
 106 
 107         /* These fields must be present in the stream */
 108         try {
 109             field3 = pfields.get("field3", 99);
 110             System.out.println("Passes test 2a");
 111         } catch(IllegalArgumentException e) {
 112             throw new Error("data field: field3 not in the persistent stream");
 113         }
 114         try {
 115             field4 = (String) pfields.get("field4", "Default string");
 116             System.out.println("Passes test 2b");
 117         } catch(IllegalArgumentException e) {
 118             throw new Error("data field: field4 not in the persistent stream");
 119         }
 120     }
 121 };
 122 
 123 class TestClass3 implements Serializable{
 124     // Not of type ObjectStreamField
 125     private final String[] serialPersistentFields =  {"Foo","Foobar"};;
 126     Integer field1;
 127     double field2;
 128     int field3;
 129     String field4;
 130 
 131     public TestClass3(Integer f1, double f2, int f3, String f4) {
 132         field1 = f1;
 133         field2 = f2;
 134         field3 = f3;
 135         field4 = f4;
 136     }
 137 
 138     private void readObject(ObjectInputStream ois)
 139         throws IOException, ClassNotFoundException {
 140         ObjectInputStream.GetField pfields = ois.readFields();
 141 
 142         field1 = (Integer) pfields.get("field1", new Integer(100));
 143         field2 = pfields.get("field2", 99.99);
 144         field3 = pfields.get("field3", 99);
 145         field4 = (String) pfields.get("field4", "Default string");
 146 
 147         try {
 148             String[] tserialPersistentFields =
 149                 (String[])pfields.get("serialPersistentFields", null);
 150             System.out.println("Passes test 3");
 151         } catch(IllegalArgumentException e) {
 152             throw new Error("non-static field:  " +
 153                 "serialPersistentFields must be in the persistent stream");
 154         }
 155     }
 156 };
 157 
 158 class TestClass4 implements Serializable {
 159     // Correct format
 160     private static final ObjectStreamField[] serialPersistentFields = {
 161         new ObjectStreamField("field1", Integer.class),
 162         new ObjectStreamField("field2", Double.TYPE),
 163     };
 164 
 165     Integer field1;
 166     double field2;
 167     int field3;
 168     String field4;
 169 
 170     public TestClass4(Integer f1, double f2, int f3, String f4) {
 171         field1 = f1;
 172         field2 = f2;
 173         field3 = f3;
 174         field4 = f4;
 175     }
 176 
 177     private void readObject(ObjectInputStream ois)
 178         throws IOException, ClassNotFoundException {
 179         ObjectInputStream.GetField pfields = ois.readFields();
 180 
 181         field1 = (Integer) pfields.get("field1", new Integer(100));
 182         field2 = pfields.get("field2", 99.99);
 183 
 184         try {
 185             field3 = pfields.get("field3", 99);
 186             throw new Error("data field: field3 in the persistent stream");
 187         } catch(IllegalArgumentException e) {
 188             System.out.println("Passes test 4a");
 189         }
 190         try {
 191             field4 = (String) pfields.get("field4", "Default string");
 192             throw new Error("data field: field4 in the persistent stream");
 193         } catch(IllegalArgumentException e) {
 194             System.out.println("Passes test 4b");
 195         }
 196     }
 197 };
 198 
 199 public class CheckModifiers {
 200     public static void main(String[] args)
 201         throws ClassNotFoundException, IOException{
 202         TestClass1 tc1 = new TestClass1(new Integer(100), 25.56, 2000,
 203             new String("Test modifiers of serialPersistentFields"));
 204 
 205         TestClass2 tc2 = new TestClass2(new Integer(100), 25.56, 2000,
 206             new String("Test modifiers of serialPersistentFields"));
 207 
 208         TestClass3 tc3 = new TestClass3(new Integer(100), 25.56, 2000,
 209             new String("Test Type of serialPersistentFields"));
 210 
 211         TestClass4 tc4 = new TestClass4(new Integer(100), 25.56, 2000,
 212             new String("Test modifiers of serialPersistentFields"));
 213 
 214 
 215         FileOutputStream fos = new FileOutputStream("fields.ser");
 216         try {
 217             ObjectOutputStream oos = new ObjectOutputStream(fos);
 218             System.out.println("Writing obj 1");
 219             oos.writeObject(tc1);
 220             System.out.println("Writing obj 2");
 221             oos.writeObject(tc2);
 222             System.out.println("Writing obj 3");
 223             oos.writeObject(tc3);
 224             System.out.println("Writing obj 4");
 225             oos.writeObject(tc4);
 226             oos.flush();
 227         } finally {
 228             fos.close();
 229         }
 230 
 231         FileInputStream fis = new FileInputStream("fields.ser");
 232         try {
 233             ObjectInputStream ois = new ObjectInputStream(fis);
 234             System.out.println("Test modifiers for serialPeristentFields ");
 235             System.out.println("---------------------------------------- ");
 236             System.out.println("Declaration missing final modifier");
 237             ois.readObject();
 238             System.out.println();
 239             System.out.println("Declaration with public instead of private access");
 240             ois.readObject();
 241             System.out.println();
 242             System.out.println("Declaration with different type");
 243             ois.readObject();
 244             System.out.println();
 245             System.out.println("Declaration as in specification");
 246             ois.readObject();
 247         } finally {
 248             fis.close();
 249         }
 250     }
 251 };
--- EOF ---