CSC/ECE 517 Fall 2009/wiki2 18 cc: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
Line 64: Line 64:


===== Example in Java =====
===== Example in Java =====
       
        import java.io.*;


<source lang="java">
        /**
import java.io.*;
        * The object to serialize.
 
        */
/**
        class ObjectToSerialize implements Serializable {
* The object to serialize.
            static private final long serialVersionUID = 42L;
*/
       
class ObjectToSerialize implements Serializable {
            private String firstAttribute;
    static private final long serialVersionUID = 42L;
            private int secondAttribute;
 
       
    private String firstAttribute;
            public ObjectToSerialize(String firstAttribute, int secondAttribute) {
    private int secondAttribute;
                this.firstAttribute = firstAttribute;
 
                this.secondAttribute = secondAttribute;
    public ObjectToSerialize(String firstAttribute, int secondAttribute) {
            }
        this.firstAttribute = firstAttribute;
       
        this.secondAttribute = secondAttribute;
            @Override
    }
            public String toString() {
 
                return firstAttribute + ", " + secondAttribute;
    @Override
            }
    public String toString() {
         }
        return firstAttribute + ", " + secondAttribute;
    }
}
 
public class Main {
    /**
    * Saves an object.
    */
    private static void saveObject(Serializable object, String filename) throws IOException {
         ObjectOutputStream objstream = new ObjectOutputStream(new FileOutputStream(filename));
        objstream.writeObject(object);
        objstream.close();
    }


        public class Main {
            /**
            * Saves an object.
            */
            private static void saveObject(Serializable object, String filename) throws IOException {
                ObjectOutputStream objstream = new ObjectOutputStream(new FileOutputStream(filename));
                objstream.writeObject(object);
                objstream.close();
            }
       
     /**
     /**
     * Loads an object.
     * Loads an object.

Revision as of 13:53, 8 October 2009

PROXY SERIALIZABLE PATTERN

Introduction

Immutable classes are used to ensure the object state never change. The concept of serialization is that applications can send and receive objects between them; this is a step further than just keeping the object alive (persistence) which is to call objects remotely, however private instances may be exposed by performing serialization. Now the problem arises when serializing an immutable class and the immutability must be preserved between applications.

The Serialization Proxy Pattern tries to handle this kind of situation, the deliverables of this wiki are: 1. Investigate how the issue described above is handled. 2. Investigate how it is designed and give details of its implementation, 3. Investigate its idiomatic usage

Definitions

When a class is immutable?

If a class state cannot be modified after being created then it is called immutable, and viceverza a mutable class can be modified after being created. There are also partially immutable classes, in which some of their attributes can be defined as immutable.

The following is an example to illustrate it:

       String  course_id= "ECE517";
       course_id.toLowerCase();

In this case the string didn’t change to lower case, it remains as “ECE517”, although the output is “ece517”, instead the output is a new string that can be assigned to other variable, therefore for the moment the values are still immutable, however the following code can change the value.

       course_id =  course_id.toLowerCase();

How to make a class immutable?

Henceforth to make a class immutable we need to keep the class state safe by any means, in other words, assignments should never occur, the following code is an example of immutable class

       final class Immutable_ece517Class 
       { 
       // To make the variables private and the term “final” is to restrict writing  
           private final string nombre; 
       
       // Constructor where we can provide the constant value 
           public Immutable_ece517Class (string paramNombre) 
           { 
              nombre = paramNombre; 
           } 
       
       // Define the methods to return variable value without writing it 
           public string getNombre
           { 
              return nombre; 
           } 
       }

The final statemente makes it immutable *****************

What is Serialization?

It is known as the process from a source application to convert an object into a sequence of bits and to store or sent them through the network, in this way the same sequence can be retrieved by another end application, it reconstructs or “clones” the original object in order to use it, this capability to store entire objects instead of simple parameters make possible to have high level distributed applications, without them the object would persist only while it is being executed (transient) and the application interaction would not be possible, e.g. remote procedure calls.

When an object is serialized its state is also recorded in the byte stream, when it is retrieved its last state is also recovered, this feature allow the possibility to save the object state in memory and retrieve for its use later by the same application, although there is also an application named as persistent that does the same, serialization can be also used as persistent object

It is also possible to serialize complex data structures like applets and complete GUI, but the scope of this wiki will be on the classes serialization.

How to serialize classes?

Java Serialization

The next step would be in how to serialize classes. In this case Java.io package offers the “writeObject()” to serialize and for un-serialize it uses “readObject( )” both are methods from ObjectOuputStream and ObjectOuputStream respectively, for an object to be serialized must have implemented the java.io.Serializable interface, the reason behind this is the security, some private classes should not be exposed when un-serialize them, this is why a class must explicity declare as serializable, Below is the code implementation in JAVA for serialization:

Link from http://en.wikipedia.org/wiki/Immutable_class don’t forget it

Example in Java
       import java.io.*;
       /**
        * The object to serialize.
        */
       class ObjectToSerialize implements Serializable {
           static private final long serialVersionUID = 42L;
       
           private String firstAttribute;
           private int secondAttribute;
       
           public ObjectToSerialize(String firstAttribute, int secondAttribute) {
               this.firstAttribute = firstAttribute;
               this.secondAttribute = secondAttribute;
           }
       
           @Override
           public String toString() {
               return firstAttribute + ", " + secondAttribute;
           }
       }
       public class Main {
           /**
            * Saves an object.
            */
           private static void saveObject(Serializable object, String filename) throws IOException {
               ObjectOutputStream objstream = new ObjectOutputStream(new FileOutputStream(filename));
               objstream.writeObject(object);
               objstream.close();
           }
       
   /**
    * Loads an object.
    */
   private static Object loadObject(String filename) throws ClassNotFoundException, IOException {
       ObjectInputStream objstream = new ObjectInputStream(new FileInputStream(filename));
       Object object = objstream.readObject();
       objstream.close();
       return object;
   }
   public static void main(String[] args) {
       ObjectToSerialize original = new ObjectToSerialize("some text", 123);
       System.out.println(original);
       try {
           saveObject(original, "object.ser");
           ObjectToSerialize loaded = (ObjectToSerialize) loadObject("object.ser");
           System.out.println(loaded);
       } catch (Exception e) {
           e.printStackTrace();
       }
   }

} </source>

Ruby Serialization

Ruby uses the methods of dump and load from the Marshal module, but not all object can be serialized like bindings, Procedures and singleton objects,

Below is the code implementation in Ruby for serialization.

class Klass
  def initialize(str)
    @str = str
  end
  def sayHello
    @str
  end
end

o = Klass.new("hello\n")
data = Marshal.dump(o)
obj = Marshal.load(data)
obj.sayHello   »  "hello\n"

The weakness in serialization is that the details of the hidden private instances may be exposed in the other end application which is not good, however in order to make remote call the end application must understand the objects, this is why serialization formats have been developed to keep proprietary software, one clear example is that a password and login should never be serialized, it is too risky if this information is exposed in the form of a serialized variable class.

The Main issue when de-serialization

The issue is that hidden private instances (immutable classes) can be exposed in the other end application and the idea is that they must remain safe and unchanged across applications. The solution proposed is the use of the Proxy Serialization Pattern


So, What is Proxy Serialization Pattern?

In general and summarized, the proxy serialization means that a class is serialized along to the method “writeReplace()” (Java), the result of this procedure is the so called “serialization proxy”, on the other end side the de-serialization process uses the “readResolve()” (Java), and the common de-serialization to reconstruct the class.

The process to make a Proxy Serialization in detail is listed below: 1. Before the serialization Java checks if the class contains the method “Object writeReplace()”. 2. If it does contain it then the return value of “Object writeReplace()” is serialized together with the class (called “Proxy Serialization”), other wise only perform normal serialization on the class. 3. The proxy serialized value is used to keep the state of the original object to write (e.g. immutability), so that in the other end application it can be reconstituted such state. 4. When de-serializing, Java checks if the class has the implementation of the method “Object readResolve()” if it does then it completes the de-serialization process and then the return value of the “readResolve()” is added to the de-serialization, which contains the state of the original object to write (e.g. immutability)

Figure XX shows the process of Proxy Serialization Pattern


The key advantage of Proxy Serialization process is that proxy is implemented as a private static nested class, in figure XX shows that its state is serialized (control of the read/write process) as well as the class itself, on the other end side the state is de-serialized (control of the read/write process) along with the class, in this way the class state is kept in the cloned class, this would keep the properties for example of an immutable implementation class.

The following code shows an example in Java; the first one is a typical immutable class, the second one is the same class with serialization proxy implemented Immutable Class

public class Tot_price {
	final int mPrice;
    final int mTax;
    public int price() { return mPrice; }
    public int tax() { return mTax; }
    public int total() {
        return price() + tax();
    }
}

Immutable Class Proxy Serialized

public class Tot_price implements Serializable {

    private final mPrice;
    private final mTax;
    public Tot_price(double price, double tax) { mPrice = price; mTax=tax; }
    ...
    private Object writeReplace() {
        return new SerializationProxy(this);
    }

    private static class SerializationProxy
        implements Serializable {

        int mPrice; int mTax;
        public SerializationProxy() { }
        public SerializationProxy(Tot_price cost) {
            mPrice = cost.price();  mTax = cost.tax();
        }
        Object readResolve() {
            return new Tot_price(mPrice,mTax);
        }
    }
}

A random serial ID number is added whenever a class is Proxy Serialized by default. However, it is highly recommended to add it within the code in order to preserve forward compatibility, otherwise if the class changes the serialize process would be aborted, the Following code shows how to add the ID number:

public class Tot_price implements Serializable {
   
    .
   
    static final long serialVersionUID = -123456789L;
   
     ...

}

Every time Java serializes an object, the ID number is computed through reflection, this causes to slow down the serializationàde-serialization process, for this reason it is recommended to define in the code the ID number.

Conclusions

kuwekwbnxkwjnx



http://stackoverflow.com/questions/702357/what-is-the-serialization-proxy-pattern http://java.sun.com/javase/6/docs/technotes/guides/serialization/

http://my.safaribooksonline.com/9781598635655/ch10lev1sec4

http://my.safaribooksonline.com/0596006209/jenut3-CHP-10

http://my.safaribooksonline.com/0130844667/ch01lev1sec4

http://en.wikipedia.org/wiki/Object_serialization

http://en.wikipedia.org/wiki/Immutable_class