/*
* Copyright 2002 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* -Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* -Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any
* kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
* WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
* EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY
* DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT OF OR
* RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR
* ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE
* FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT,
* SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
* THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that Software is not designed, licensed or
* intended for use in the design, construction, operation or
* maintenance of any nuclear facility.
*/
import java.io.*;
import java.util.*;
/**
* When Java objects use serialization to store objects, the potential arises
* that the version of the class reading the data is different from the version
* of class that wrote that data
*
* This example demonstratres some of the compatible changes that Serialization
* handles without class-specific methods
*
* For directions of How to Run: see the Original Class file.
*
* Compiled and Tested with JDK1.2
* This file contains the evolved class.
* The original class is in file called EvolutionExampleOriginalClass.java
*/
public class EvolutionExampleEvolvedClass {
/**
* There are two options: either a user can serialize an object or
* deserialize it. (using the -s or -d flag). These options allow
* for the demonstration of bidirection readability and writeability
* between the original and the evolved class. In other words,
* one can serialize an object here and deserialize it with the evolved
* class or vice versa.
*/
public static void main(String args[]) {
AClass serializeclass = new AClass(20, "serializedByEvolvedClass");
AClass deserializeclass = null;
boolean serialize = false;
boolean deserialize = false;
/*
* see if we are serializing or deserializing.
* The ability to deserialize or serialize allows
* us to see the bidirectional readability and writeability
*/
if (args.length == 1) {
if (args[0].equals("-d")) {
deserialize = true;
} else if (args[0].equals("-s")) {
serialize = true;
} else {
usage();
System.exit(0);
}
} else {
usage();
System.exit(0);
}
/*
* Serialize the original class if that's the option chosen
*/
if (serialize) {
try {
FileOutputStream fo = new FileOutputStream("evolve.tmp");
ObjectOutputStream so = new ObjectOutputStream(fo);
so.writeObject(serializeclass);
so.flush();
} catch (Exception e) {
System.out.println(e);
System.exit(1);
}
}
/*
* Deserialize, if that's the option chosen and print the name
* of the object, which will allow us to see who serialized the
* object, the original class or the evolved class file
*/
if (deserialize) {
try {
FileInputStream fi = new FileInputStream("evolve.tmp");
ObjectInputStream si = new ObjectInputStream(fi);
deserializeclass = (AClass) si.readObject();
} catch (Exception e) {
System.out.println(e);
System.exit(1);
}
/*
* Print out to see that it is indeed the same object as it was
* when it was serialized (depending on whether it was the original
* class that serialized it or the evolved class)
*/
System.out.println("Now printing deserialized object's name: ");
System.out.println();
System.out.println("name: " + deserializeclass.name);
System.out.println();
}
}
/**
* Prints out the usage
*/
static void usage() {
System.out.println("Usage:");
System.out.println(" -s (in order to serialize)");
System.out.println(" -d (in order to deserialize)");
}
}
/**
* Evolved Class
* Has the following compatible changes
* 1) add a field
* 2) change a access to a field (for example -> public to private)
* 3) Remove the writeObject/readObject methods
* 4) change a static field to non-static - this is equivalent to adding
* a field.
* Compatible changes that are NOT demonstrated by this example
* 1) Adding classes/Removing classes
* 2) Adding writeObject/readObject methods
*/
class AClass implements Serializable {
// mandatory suid field (gotten using serialver on the original Aclass)
static final long serialVersionUID = -6756364686697947626L;
// Change: removed the private
/**
* @serial
*/
int num;
// Change: added this field
/**
* @serial
*/
boolean b;
/**
* @serial
*/
String name;
// Change: removed the static.. so this field will now be serialized
// equivalent to adding a field
/**
* @serial
*/
Hashtable ht = new Hashtable();
// ...
// ...
// ...
AClass(int n, String s) {
num = n;
name = s;
boolean b = true;
}
// some methods...
// ...
// ...
/**
* These writeObject and readObject merely defaultwriteObject and
* defaultreadObject - so they don't do anything.. but they are placed
* here so that we can show that we can remove them in the evolved
* class without any effect.
*
* @serialData Write serializable fields. No optional data written.
*/
private void writeObject(ObjectOutputStream s)
throws IOException {
s.defaultWriteObject();
}
/**
* readObject - just calls defaultreadObject()
*
* @serialData Read serializable fields. No optional data read.
*/
private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException {
s.defaultReadObject();
}
}