Friday, May 30, 2014

Producer Consumer Problem's solution in Java

From the Wikipedia definition,  the producer–consumer problem (also known as the bounded-buffer problem) is a classic example of a multi-process synchronization problem. The problem describes two processes, the producer and the consumer, who share a common, fixed-size buffer used as a queue. The producer's job is to generate a piece of data, put it into the buffer and start again. At the same time, the consumer is consuming the data (i.e., removing it from the buffer) one piece at a time. The problem is to make sure that the producer won't try to add data into the buffer if it's full and that the consumer won't try to remove data from an empty buffer.
The solution for the producer is to either go to sleep or discard data if the buffer is full. The next time the consumer removes an item from the buffer, it notifies the producer, who starts to fill the buffer again. In the same way, the consumer can go to sleep if it finds the buffer to be empty. The next time the producer puts data into the buffer, it wakes up the sleeping consumer. The solution can be reached by means of inter-process communication. An inadequate solution could result in a deadlock where both processes are waiting to be awakened. The problem can also be generalized to have multiple producers and consumers.

In this post I am sharing my producer-consumer solution written in Java.

Producer class:

import java.util.Vector;

public class MyProducer implements Runnable{
 /*taking vector to use as buffer, 
         *it will keep numbers produced by Producer 
  *and work as synchronisation object
        */
 Vector<Integer> sharedQ;
 // Size will store the maximum size of buffer
 int SIZE;
 /*
  * Constructor for Producer class
  */
 public MyProducer(Vector<Integer> sharedQ, final int size) {
  this.sharedQ =sharedQ;
  this.SIZE= size;
 }
 @Override
 public void run() {
  int i=0;
  while(true){
   i++;
   produce(i);
  }
 }
 /*
  * This method has the logic for producing numbers 
         *and synchronization with consumer
  */
 public void produce(int i) {
  //testing if buffer is already full
  while(sharedQ.size() == SIZE) {
   synchronized (sharedQ) {
    try {
     System.out.println("producer waiting...");
     //waiting until some space is made in buffer
     sharedQ.wait();
    } catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
   }
  }
  //adding numbers in buffer
  synchronized(sharedQ) {
   sharedQ.add(i);
   System.out.println("Producer produced: "+i);
   //notifying other thread which are waiting on sharedQ
   sharedQ.notifyAll();
  }
  try {
   /*
    * making thread to sleep for random time after producing  
    *so as to make output more readable and understandable
    *we can set any arbitrary sleeping time
    */
   Thread.sleep(((long)((Math.random())*10000)));
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }
}


Consumer class:

import java.util.Vector;

public class MyConsumer implements Runnable {
 
        /*taking vector to use as buffer, 
         *it will keep numbers produced by Producer 
  *and work as synchronisation object
        */ 
        Vector<Integer> sharedQ;
 
 public MyConsumer(Vector<Integer> sharedQ) {
  this.sharedQ = sharedQ;
 }
 
 @Override
 public void run() {
  /*
   * loop will go on forever
   */
  while(true) {
      consumed();
     /*
      * making thread to sleep for random time after consuming  
      *so as to make output more readable and understandable
      *we can set any arbitrary sleeping time
      */
      try {
   Thread.sleep(((long)((Math.random())*20000)));
   
      } catch (InterruptedException e) {   
   e.printStackTrace();
      }
       }
 }
 /*
  * This method has the logic for consuming numbers 
         *and synchronization with producer
  */
 public void consumed() {
  // cheacking if buffer is empty-then consumer has to wait
   while(sharedQ.isEmpty()) {
    synchronized(sharedQ) {
     try {
      System.out.println(Thread.currentThread().getName()+" waiting...");
      sharedQ.wait();
     } catch (InterruptedException e) {
      
      e.printStackTrace();
     }
     
    }
   }
   //consuimng a number from the buffer
   synchronized(sharedQ) {
      System.out.println(Thread.currentThread().getName()+" consumed "+sharedQ.remove(0));
      //notifying other thread which are waiting on sharedQ
      sharedQ.notifyAll();
   }
  }
 
}

  Test class:

import java.util.Vector;

public class MyProducerConsumerTest { 
 
 public static void main(String args[]) {
  
        /*taking vector to use as buffer, 
         *it will keep numbers produced by Producer 
  *and work as synchronisation object
         */  
        Vector<Integer> sharedQ = new Vector<Integer>();
        // Size will store the maximum size of buffer
  final int SIZE = 5;
 //Making producer and consumer thread
 Thread producer = new Thread(new MyProducer(sharedQ,SIZE),"producer");
 Thread consumer = new Thread(new MyConsumer(sharedQ),"consumer");
  
 //starting producer/consumer threads
 producer.start();
 consumer.start();
 /*
  * this join is optional- 
  * after join this main thread will never finish as consumer/producer willl run forever
  * to see effect of join we need to make consumer/producer to run for some specific time
  */
  
 try {
  producer.join();
  consumer.join();
   
 } catch (InterruptedException e) {   
  e.printStackTrace();
 }
 /*
  * this will never get printed 
  * unless we remove join call made above or finish execution of producer/consumer threads
  */
 System.out.println("all done");
 }
}

We can make this code to work for multiple producer/consumer scenario just by changing test class and creating multiple threads for producer and consumer.

Modified Test class:

import java.util.Vector;

public class MyProducerConsumerTest { 
 
 public static void main(String args[]) {
  
        /*taking vector to use as buffer, 
         *it will keep numbers produced by Producer 
  *and work as synchronisation object
         */  
        Vector<Integer> sharedQ = new Vector<Integer>();
        // Size will store the maximum size of buffer
  final int SIZE = 5; 
 
     //Making producer and consumer thread
 Thread producer1 = new Thread(new MyProducer(sharedQ,SIZE),"producer1");
        Thread producer2 = new Thread(new MyProducer(sharedQ,SIZE),"producer2"); 
        Thread producer3 = new Thread(new MyProducer(sharedQ,SIZE),"producer3");
        Thread consumer1 = new Thread(new MyConsumer(sharedQ),"consumer1");
        Thread consumer2 = new Thread(new MyConsumer(sharedQ),"consumer2");
        Thread consumer3 = new Thread(new MyConsumer(sharedQ),"consumer3");
        Thread consumer4 = new Thread(new MyConsumer(sharedQ),"consumer4"); 
  
       //starting producer/consumer threads
 producer1.start();
        producer2.start();
        producer3.start(); 
        consumer1.start();
        consumer2.start();
        consumer3.start();
       consumer4.start(); 
        /*
  * this join is optional- 
  * after join this main thread will never finish as consumer/producer willl run forever
  * to see effect of join we need to make consumer/producer to run for some specific time
  */
  
 try {
  producer1.join();
                producer2.join();
               producer3.join(); 
                consumer1.join();
                consumer2.join();
                consumer3.join();
                consumer4.join(); 
        } catch (InterruptedException e) {   
  e.printStackTrace();
 }
 /*
  * this will never get printed 
  * unless we remove join call made above or finish execution of producer/consumer threads
  */
 System.out.println("all done");
 }
}

 

 

Thursday, May 29, 2014

immutability in Java

An object is considered immutable if its state cannot change after it is constructed.

Immutable objects are particularly useful in concurrent applications. Since they cannot change state, they cannot be corrupted by thread interference or observed in an inconsistent state.

Strategy for Defining Immutable Objects

The following rules define a simple strategy for creating immutable objects.
  1. Don't provide "setter" methods — methods that modify fields or objects referred to by fields.
  2. Make all fields final and private.
  3. Set all instance data in the constructor.
  4. Don't allow sub-classes to override methods. The simplest way to do this is to declare the class as final. A more sophisticated approach is to make the constructor private and construct instances in factory methods.
  5. If the instance fields include references to mutable objects, don't allow those objects to be changed:
    • Don't provide methods that modify the mutable objects.
    • Clone mutable objects for which a reference to them is returned.
    • Clone mutable objects for which a reference to them is received.
    • Implement a deep clone if the default shallow clone is not correct for a properly behaved immutable object.
 Lets add all above rules and make something concrete class implementation.
By making class final:

This is the most simple way of making a class mutable.
public final class FinalPersonClass {       

      private final String name;
      private final int age;      

      public FinalPersonClass(final String name, final int age) { 

            super();
            this.name = name;
            this.age = age; 
      } 

      public int getAge() { 

            return age;
      } 

      public String getName() { 

            return name;
      }
} 

 Using Factory methods and making constructor private:

//No need to make class final here 
public class FinalPerson { 
          
     private final String name;
      private final int age;       

      private FinalPerson(final String name, final int age) { 

            super();
            this.name = name;
            this.age = age;
      } 

      public int getAge() { 

            return age;
      } 

      public String getName() { 

            return name; 
      } 

      public FinalPerson getFinalPerson(final String name, final int age) {
           return new FinalPerson(final String name, final int age);
     }
} 


Making a class immutable in Java, which includes mutable member variable.

When an immutable class is implemented, mutable objects passed to or returned from an immutable object must be properly cloned. Consider the following class declarations: a DiskDriveInfo class and a User class. The DiskDriveInfo is intended to be immutable. The User encapsulates which user has shared access to the disk drive. The User object with shared access is stored as part of the DiskDriveInfo object. In the following example, the designer of the class was careful to make the class final and all fields private, and to provide only getter methods. Is the DiskDriveInfo class immutable? If not, what needs to be done to make it so?

class User
{
  private String userName;
  private String userID;
  private int userNode;

  User(String name, int node)
  {
    userName = name;
    userNode = node;
  }
  public void setUserName(String name)
  {
    userName = name;
  }
  public void setUserID(String userid)
  {
    userID = userid;
  }
  public void setUserNode(int node)
  {
    userNode = node;
  }
  public String userName()
  {
    return userName;
  }
}


final class DiskDriveInfo
{
  private int driveSize;
  private String volumeLabel;
  private User driveShare;

  DiskDriveInfo(int size, String volLabel, User share)
  {
    driveSize = size;
    volumeLabel = volLabel;
    driveShare = share;
  }
  public int size()
  {
    return driveSize;
  }
  public String label()
  {
    return volumeLabel;
  }
  public User share()
  {
    return driveShare;
  }
}

The DiskDriveInfo class is not immutable. Objects of this class can be changed. Consider the following code that creates a DiskDriveInfo object and tests its immutability:

class Test
{
  private static final int sizeInMeg = 200;
  public static void main(String args[])
  {
    User share1 = new User("Duke", 10);                       //1
    DiskDriveInfo dd = new DiskDriveInfo(sizeInMeg, "myDrive",
                                         share1);             //2
    User share = dd.share();
    System.out.println("User with shared access is " +
                       share.userName());

    share1.setUserName("Fred");                               //3
    System.out.println("User with shared access is " +
                       share.userName());
  }
}

If we run the program we will get output like this:

Output
================================================================================
User with shared access is Duke
User with shared access is Fred
What went wrong? This code creates a User object, share1, at //1, with the user name Duke. A supposedly immutable DiskDriveInfo object is created at //2 and is passed a reference to the User object. The DiskDriveInfo object is queried, and the shared owner, Duke, is printed. The User object, share1, changes its name to Fred at //3. When the DiskDriveInfo object is queried again for the user name, it discovers that the name changed from Duke to Fred.
The problem is that the DiskDriveInfo constructor receives a reference to the User object and does not make a copy, or clone, of this object. Therefore, the DiskDriveInfo constructor receives a copy of the reference to the User object. Now the DiskDriveInfo object's driveShare field and the local variable, share1, in main of class Test, reference the same object. Therefore, any changes made through either reference affect the same object. Figure shows the object layout after the code at //1 is executed.




http://ptgmedia.pearsoncmg.com/images/art_haggar2_praxis64/elementLinks/haggar2_fig1.gif
 
After the code at //2 is executed, the object layout looks as shown in Figure

http://ptgmedia.pearsoncmg.com/images/art_haggar2_praxis64/elementLinks/haggar2_fig2.gif
Notice that because the reference to the User object is not cloned, both the share1 and driveShare references share the same User object. After the code at //3 is executed, the object layout as shown in Figure.

http://ptgmedia.pearsoncmg.com/images/art_haggar2_praxis64/elementLinks/haggar2_fig3.gif

To correct this problem, the DiskDriveInfo class must clone any mutable object to which it receives a reference. It then has a reference to its own copy of the object that cannot be changed by other code.
The modified DiskDriveInfo class that supports cloning looks like this:


final class DiskDriveInfo
{
  //As before...
  DiskDriveInfo(int size, String volLabel, User share)
  {
    driveSize = size;
    volumeLabel = volLabel;
    driveShare = (User)share.clone();
  }
  public User share()
  {
    return (User)driveShare.clone();
  }
}

 Because you are cloning the User object, its definition must change as well.


class User implements Cloneable
{
  //As before...
  public Object clone()
  {
    try {
      return super.clone();
    }
    catch (CloneNotSupportedException e) {
      //This should not happen, since this class is Cloneable.
      throw new InternalError();
    }
  }
}

 With these changes to the User object, running the previous test code produces the correct output:
Output
================================================================================
User with shared access is Duke
User with shared access is Fred
Because the User object is cloned on the constructor call, the code that subsequently changes the User object at //1 has no effect on the DiskDriveInfo object. The implementation of the immutable DiskDriveInfo class is now correct. The object layout looks as shown in Figure

http://ptgmedia.pearsoncmg.com/images/art_haggar2_praxis64/elementLinks/haggar2_fig4.gif

Achieving Immutability with Builder Design Pattern:

In most of the classes in our real applications there are many fields. Also, most of these fields are not mandatory for object creation. For example, a user in a real application will have a username, password, firstname, lastname, creationDate, emailAddress, etc., but for user creation here, only a username and password are required. 

The Builder Pattern separates the construction of a complex object from its representation so that the same construction process can create different representations.
The builder design pattern provides a way for you to build complex immutable objects. The process is:
  1. The client calls a constructor (or static factory) with all the required parameters and gets a builder object.
  2. The client calls setter like methods to set each optional parameter of interest.
  3. Finally the client calls the build method to generate the object which is immutable.

import java.math.BigDecimal;

/**
* Immutable, hence thread safe CashBalance objec
*/

public final class CashBalance {
  
 private BigDecimal initialBalance, totCredits, totDebits;
  
  //construct
  public CashBalance(CashBalanceBuilder builder) {
  this.initialBalance = builder.initialBalance;
  this.totCredits = builder.totCredits;
  this.totDebits = builder.totDebits;
 }
    
 public static class CashBalanceBuilder {
   
  //has same fields as the object it is going to build
   protected BigDecimal initialBalance, totCredits, totDebits;
  //define the setters that return itself
   CashBalanceBuilder setInitialBalance(BigDecimal initialBalance) {
   this.initialBalance = initialBalance;
   return this;
  }
   CashBalanceBuilder setTotCredits(BigDecimal totCredits) {
    this.totCredits = totCredits;
   return this;
  }
  CashBalanceBuilder setTotDebits(BigDecimal totDebits) {
   this.totDebits = totDebits;
   return this;
  }
 }
  
 //only getter methods and no setter methods as it is an immutable object
}

The client code will look like this :


public static void main(String[] args) {
   CashBalance.CashBalanceBuilder builder = 
           new CashBalance.CashBalanceBuilder(
                    .setInitialBalance(BigDecimal.valueOf(250.00))
                    .setTotCredits(BigDecimal.valueOf(250.00))
                    .setTotDebits(BigDecimal.valueOf(250.00));
                    CashBalance bal = new CashBalance(builder);
}

How to use Date object in immutable class

This is a commonly asked scenario in interviews while discussing about immutable classes.
Some time you may need to write immutable class which includes mutable classes like java.util.Date, despite storing Date into final field it can be modified internally, if internal date is returned to the client. In order to preserve immutability in such cases, its advised to return copy of original object.
Consider the below code:

public final class ImmutableReminder{

    private final Date remindingDate;
  

    public ImmutableReminder (Date remindingDate)
    {
        if(remindingDate.getTime() < System.currentTimeMillis()){

            throw new IllegalArgumentException("Can not
                   set reminder” + “ for past time: " + remindingDate);
         }
         // creating new object of Date first
this.remindingDate = new Date(remindingDate.getTime());
    }

    public Date getRemindingDate() {
      //returning clone of the date object 
     return (Date) remindingDate.clone();
    }
} 


Wednesday, May 28, 2014

serialVersionUID


When you serialize an object using Serialization mechanism (by implementing Serializable interface), there is a possibility that you may face versioning issues and because of these versioning issues, you will not be able to deserialize the object.



Sections in this post: 
  1. Problem to face
  2. Root of the problem
  3. Solution
  4. What is serialVersionUID
  5. Example
  6. When to update serialVersionUID
    1. Compatible changes
    2. Incompatible changes


Problem scenario....

lets say you created a class, instantiated it, and wrote it out to an object stream. That flattened object sits in the file system for some time. Meanwhile, you update the class file, perhaps adding a new field. Now try to read the flattened object. An exception "java.io.InvalidClassException" will be thrown.

 Root of the problem

lets first see what is actually causing this problem? Why should any change in a serialized class throw "InvalidClassException". During object serialization, the default Java serialization mechanism writes the metadata about the object, which includes the class name, field names and types, and superclass. All this information is stored as part of the serialized object.
When you deserialize the object, this information is read to reconstitute the object. But to perform the deserialization, the object needs to be identified first and this will be done by serialVersionUID. So everytime an object is serialized the java serialization mechanism automatically computes a hash value using ObjectStreamClass’s computeSerialVersionUID() method by passing the class name, sorted member names, modifiers, and interfaces to the secure hash algorithm (SHA), which returns a hash value, the serialVersionUID.

Now when the serilaized object is retrieved, the JVM first evaluates the serialVersionUID of the serialized class and compares the serialVersionUID value with the one of the object. If the sserialVersionUID values match then the object is said to be compatible with the class and hence it is de-serialized. If not InvalidClassException exception is thrown.

 And the solution is...

The solution is very simple. Instead of relying on the JVM to generate the serialVersionUID, you explicitly mention (generate) the serialVersionUID in your class. The syntax is:


 private final static long serialVersionUID = <integer value> 


What is serialVersionUID? 

Its a static, private variable in the class. Once you define the serialVersionUID in your class explicitly, you don't need to update it until and unless you make the incompatible changes.
 
Example:

Consider the same example taken from serialization post to explain the issue and importance of maintaining serialVersionUID.

 

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;

public class MyDateObject implements Serializable{
  
    //first time we keep serial VersionUID as 1L
    private static final long serialVersionUID = 1L;
    private Date date;

    public MyDateObject() {
        //date= Calendar.getInstance().getTime();
         calculateCurrentTime();
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date=date;
     }
   
    private void calculateCurrentTime(){
        date = Calendar.getInstance().getTime();
    }
   
    private void writeObject(ObjectOutputStream out) throws IOException {
        out.defaultWriteObject();
    }

    private void readObject(ObjectInputStream in)
        throws IOException, ClassNotFoundException{

        // our "pseudo-constructor"
        in.defaultReadObject();
        // now perfrom same operation you need to do in constructor
        calculateCurrentTime();
    }
}

 Class to serialize MayDate object :



import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

//Class to persist the time in a flat file time.ser
public class WriteSerialClass {

  public static void main(String [] args) {
      String filename = "c://time.txt";

      if(args.length > 0){
          filename = args[0];
      }
      
      MyDateObject time = new MyDateObject();
      FileOutputStream fos = null;
      ObjectOutputStream out = null;

      try{
          fos = new FileOutputStream(filename);
          out = new ObjectOutputStream(fos);
          out.writeObject(time);
          out.close();
      }catch(IOException ex){
          ex.printStackTrace();
      }
   }

Class to De-serialize MydateObject:


import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Calendar;

public class ReadSerialClass   {

     public static void main(String [] args) {
            String filename = "c://time.txt";

            if(args.length > 0){
                filename = args[0];
            }
           
            MyDateObject time = null;
            FileInputStream fis = null;
            ObjectInputStream in = null;

            try{
                fis = new FileInputStream(filename);
                in = new ObjectInputStream(fis);
                time = (MyDateObject)in.readObject();
                in.close();
            }catch(IOException ex){
                ex.printStackTrace();
            }catch(ClassNotFoundException cnfe){
                cnfe.printStackTrace();
            }

            // print out restored time
            System.out.println("Restored time: " + time.getDate());

            // print out the current time
            System.out.println("Current time: "
                + Calendar.getInstance().getTime());

         }
     } 
Output:
=======================================================
Restored time: Wed May 28 18:11:41 IST 2014
Current time: Wed May 28 18:11:42 IST 2014
 
 

 Now run the following program again by changing serialVersionUID value in myDateObject class:


 
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;

public class MyDateObject implements Serializable{
  
   //Now we change serial VersionUID as 2L
    private static final long serialVersionUID = 2L;
    private Date date;

    public MyDateObject() {
        //date= Calendar.getInstance().getTime();
         calculateCurrentTime();
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date=date;
     }
   
    private void calculateCurrentTime(){
        date = Calendar.getInstance().getTime();
    }
   
    private void writeObject(ObjectOutputStream out) throws IOException {
        out.defaultWriteObject();
    }

    private void readObject(ObjectInputStream in)
        throws IOException, ClassNotFoundException{

        // our "pseudo-constructor"
        in.defaultReadObject();
        // now perfrom same operation you need to do in constructor
        calculateCurrentTime();
    }
}
Output:
=========================================================
java.io.InvalidClassException: com.MyDateObject; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2
    at java.io.ObjectStreamClass.initNonProxy(Unknown Source)
    at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
    at java.io.ObjectInputStream.readClassDesc(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source) 

 The reason of the above error is the version change and exactly this is the reason for maintaining the version.
By maintaining version we keep the serialization/de-serialiation consistent

When to update serialVersionUID?

Adding serialVersinUID manually to the class does not mean that it should never be updated and never need not be updated. There is no need to update the serialVersionUID if the change in the class is compatible but it should be updated if the change is incompatible

Some of compatible changes are:
  • Adding field.
  • Adding classes.
  • Removing classes.
  • Adding writeObject/readObject methods.
  • Removing writeObject/readObject methods.
  • Adding java.io.Serializable.
  • Changing the access to a field.
  • Changing a field from static to nonstatic or transient to nontransient.
  Some of the Incompatible changes  are:
  • Deleting fields.
  • Moving classes up or down the hierarchy.
  • Changing a nonstatic field to static or a nontransient field to transient.
  • Changing the declared type of a primitive field.
  • Changing the writeObject or readObject method.
  • Changing a class from Serializable to Externalizable or visa-versa.
  • Removing either Serializable or Externalizable. 
  • Adding the writeReplace or readResolve method. 


Serialization in Java


Serialization is the process of converting an object's state (including its references) to a sequence of bytes, as well as the process of rebuilding those bytes into a live object at some future time.

Sections in this post: 
  1. Some uses of serailization
  2. Serializable Interface
  3. Serialization steps
  4. readObject and writeObjectMethods
  5. FAQ

Serialization is used when you want to persist the object. It is also used by RMI to pass objects between JVMs, either as arguments in a method invocation from a client to a server or as return values from a method invocation. In general, serialization is used when we want the object to exist beyond the lifetime of the JVM. 


Here are some uses of serialization
  • To persist data for future use.
  • To send data to a remote computer using such client/server Java technologies as RMI or socket programming.
  • To "flatten" an object into array of bytes in memory.
  • To exchange data between applets and servlets.
  • To store user session in Web applications.
  • To activate/passivate enterprise java beans.
  • To send objects between the servers in a cluster. 

Java provides Serialization API, a standard mechanism to handle object serialization. To persist an object in java, we need to follow following steps.
  1.  the first step is to flatten the object. For that the respective class should implement "java.io.Serializable" interface. We don't need to implement any methods as this interface do not have any methods. This is a marker interface/tag interface. Marking a class as Serializable indicates the underlying API that this object can be flattened. 


import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;

public class MyDateObject implements Serializable{

    private static final long serialVersionUID = -5315058568373987829L;
    private Date date;

    public MyDateObject() {
        date= Calendar.getInstance().getTime();
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date=date;
     }
}

     2.  Next step is to actually persist the object. To persist an object we need to use node stream to write to file systems or transfer a flattened object across a network. We can use java.io.ObjectOutputStream class for this. So to write an object you use "writeObject(<<instance>>)" method of "java.io.ObjectOutputStream" class and to read an object you use "readObject()" method of "java.io.ObjectOutputStream" class.

Note:  "readObject()" can read only serialized object, that means if the class does not implement "java.io.Serializable" interface, "readObject()" cannot read that object.


import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;


//Class to persist the time in a flat file time.txt
public class WriteSerializeClass {

  public static void main(String [] args) {
       String filename = "c://time.txt";
       if(args.length > 0){
          filename = args[0];
       }       

      MyDateObject time = new MyDateObject();
      FileOutputStream fos = null;
      ObjectOutputStream out = null;

      try{

          fos = new FileOutputStream(filename);
          out = new ObjectOutputStream(fos);
          out.writeObject(time);
          out.close();
      }catch(IOException ex){
          ex.printStackTrace();
      }
   }
}

    

 
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Calendar;
//Class to read the time from a flat file time.txt
public class ReadSerializeClass   {

  public static void main(String [] args) {
         String filename = "c://time.txt";

         if(args.length > 0){
             filename = args[0];
         }
   
         MyDateObject time = null;
         FileInputStream fis = null;
         ObjectInputStream in = null;

         try{
             fis = new FileInputStream(filename);
             in = new ObjectInputStream(fis);
             time = (MyDateObject)in.readObject();
             in.close();
         }catch(IOException ex){
             ex.printStackTrace();
         }catch(ClassNotFoundException cnfe){
             cnfe.printStackTrace();
         }

         // print out restored time
         System.out.println("Restored time: " + time.getDate());

         // print out the current time
         System.out.println("Current time: " 
                      + Calendar.getInstance().getTime());
      }
  }

readObject and writeObject methods:

 To enhance the normal process of serialization/de-serialization provide two methods inside your serializable class. Those methods are:
  1. private void writeObject(ObjectOutputStream out) throws IOException;
  2. private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException; 
   Let's look at one example

Without readObjet()/writeObject()

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;

public class MyDateObject implements Serializable{
    
 
    private static final long serialVersionUID = -5315058568373987829L;
    private Date date;

    public MyDateObject() {
        //date= Calendar.getInstance().getTime();
        calculateCurrentTime();
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
     this.date=date;
     } 
    
    private void calculateCurrentTime(){
        date = Calendar.getInstance().getTime();
    }
 }
Output:
=================================================================

 Restored time: Wed May 28 15:54:31 IST 2014
Current time: Wed May 28 15:54:34 IST 2014

Now we will add the two methods:  readObjet()/writeObject()


import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;

public class MyDateObject implements Serializable{    
 
   private static final long serialVersionUID = -5315058568373987829L;
   private Date date;

    public MyDateObject() {
        //date= Calendar.getInstance().getTime();
        calculateCurrentTime();
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date=date;
     } 
    
    private void calculateCurrentTime(){
        date = Calendar.getInstance().getTime();
    }    //Adding writObject()
    private void writeObject(ObjectOutputStream out) throws IOException {
        out.defaultWriteObject();
    }      //Adding readObject()
    private void readObject(ObjectInputStream in) 
                         throws IOException, ClassNotFoundException{

         in.defaultReadObject();
        // now perfrom same operation you need to do in constructor
        calculateCurrentTime();
    }
}

Output:
=========================================================================
Restored time: Wed May 28 16:08:26 IST 2014
Current time: Wed May 28 16:08:26 IST 2014

 So by overriding these two methods, we can easily get desired serialization/de-serialization behavior.

Note:  serialization does not care about access modifiers. It serializes all private, public and protected fields.

Again there is one more way to serialize the object - create your own protocol with the Externalizable interface. Instead of implementing the Serializable interface, you can implement Externalizable, which contains two methods:
  1. public void writeExternal(ObjectOutput out) throws IOException; 
  2. public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;
The Externalization is discussed as separate post. Check it out here .

Some FAQ:
  1. why readObject And writeObject declared as private?
     Ans:  We don't want these methods to be overridden by subclasses. Instead, each class can have its own writeObject method, and the serialization engine will call all of them one after the other. This is only possible with private methods (these are not overridden). (The same is valid for readObject.)
That's why  both methods are declared private . The trick here is that the virtual machine will automatically check to see if either method is declared during the corresponding method call. The virtual machine can call private methods of your class whenever it wants but no other objects can. Thus, the integrity of the class is maintained and the serialization protocol can continue to work as normal. 

 2. How stop from serailizing one of the sub class of a serializable class?

Ans:To stop the automatic serialization, we can once again override the readObject/writeObject  methods to just throw the NotSerializableException in our class.


private void writeObject(ObjectOutputStream out) throws IOException{

    throw new NotSerializableException("Dont Serialize");
}

private void readObject(ObjectInputStream in) throws IOException{

    throw new NotSerializableException("Dont Serialize");
}

     





Monday, May 12, 2014

Simple Example to show Dependency inversion using Spring

This is a simple example to explain difference between a program having dependency inversion and one without it.

First we will see program without Dependency Inversion.

Example code without Dependency Inversion

public class VotingBooth {

      VoteRecorder voteRecorder = new VoteRecorder();

       public void vote(Candidate candidate) {
             voteRecorder.record(candidate);
       }

       class VoteRecorder {
             Map hVotes = new HashMap();

             public void record(Candidate candidate) {

                    int count = 0;
                    if (!hVotes.containsKey(candidate)){
                            hVotes.put(candidate, count);
                     } else {
                           count = hVotes.get(candidate);
                     }

                     count++;
                     hVotes.put(candidate, count);
            }
     }
}
In this example, the VotingBooth class is directly dependent on VoteRecorder, which has no abstractions and is the implementing class.

A dependency “inverted” version of this code might look a little different. First, we would define our VoteRecorder interface.

Code with Dependency Inversion in Spring:

We can use our code exactly as is. All we need to do is inform Spring through an XML configuration file that the recorder bean is implemented by the LocalVoteRecorder class. We do this with the following line:

public interface VoteRecorder {
       public void record(Candidate candidate) ;
}
And our implementing classes

The LocalVoteRecorder, which implements the VoteRecorder interface:

public class LocalVoteRecorder implements VoteRecorder {

      Map hVotes = new HashMap();

      public void record(Candidate candidate) {

            int count = 0;

            if (!hVotes.containsKey(candidate)){
                      hVotes.put(candidate, count);
            } else {
                     count = hVotes.get(candidate);
            }

            count++;
            hVotes.put(candidate, count);
    }
}
And the VotingBooth class:

public class VotingBooth {
     VoteRecorder recorder = null;

     public void setVoteRecorder(VoteRecorder recorder) {
          this.recorder = recorder;
     }

     public void vote(Candidate candidate) {
         recorder.record(candidate);
 }

  Now all we need to do is inform Spring through an XML configuration file that the recorder bean is implemented by the LocalVoteRecorder class. We do this with the following line:

<bean id="recorder" class="com.springindepth.LocalVoteRecorder" />
Then we simply map the recorder bean to the VotingBooth bean by setter injection in that beans definition.

<bean id="votingBooth" class="com.springindepth.VotingBooth">
     <property name="voteRecorder" ref="recorder"/>
</bean>
**Example taken from http://www.springbyexample.org/