Sunday, November 6, 2016

Tiniest Module Container (Serialization)

This post builds on previous posts:
Today we have a look at a Java concept that we will make extensive use of during the development of this project:


Serialization in Java

Serialization is a built-in Java concept that allows us to save (persist) the state of a Java object (instance) to a Stream. In our example, we save it to the hard drive as a file.



Implementation

The concept is relatively easy to implement, all you have to do is to add
implements java.io.Serializable to your class definition.

Be aware that you need to do this for all of your classes that might end up being persistable properties!

I wrote a utility class that contains the code needed to effectuate the persisting and loading of an instance's state:

The Serializer



/**
 * @author      Michael Appelt 
 * @version     0.1 Initial          
 * @since       0.1  
 * @copyright   2016/2017 Michael Appelt        
 */
package appiappelt.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;

import appiappelt.shell.Shell;

public class Serializer {

 /**
  * Persist state to disk
  * @throws IOException 
  */
 public static void persist(Object obj) throws IOException {
  if (obj instanceof Serializable) {
      String className = obj.getClass().getName();
             className = className.replace('.', '_');
      OutputStream file = new FileOutputStream(Shell.getCurrentDir()+File.separatorChar+className+".dat");
      OutputStream buffer = new BufferedOutputStream(file);
      ObjectOutput output = new ObjectOutputStream(buffer);
      output.writeObject(obj); 
      output.close();   
  }
 }
 
 /**
  *  Load persisted state
  * @param  obj - The object wanting its persistent state
  * @return a new object representing the loaded state. do remember to copy properties
  * @throws IOException
  * @throws ClassNotFoundException
  */
 public static Object loadState(Object obj) throws IOException, ClassNotFoundException {
  if (obj instanceof Serializable) {
       String className = obj.getClass().getName();
       className = className.replace('.', '_');
       InputStream file = new FileInputStream(Shell.getCurrentDir()+File.separatorChar+className+".dat");
       InputStream buffer = new BufferedInputStream(file);
       ObjectInput input = new ObjectInputStream (buffer);
       obj = input.readObject();
       input.close();
  } else {
       return null;
  }
  return obj;
 }
}
The File name is composed of the current directory String* (operating System independent I hope), the class name ('.' replaced by '_') and a ".dat" as the file type.

*I want that the state is saved within the directory "where the Shell is running". We will "parameterize" this at a later stage.

The loading of the state is nothing else but reading the state out of the File Stream and assigning it to the receiving object instance.



Application

You can see the usage of the Serializer in the JUnit test method below:


Let's unwrap the code above:

  1. We first instantiate a Shell object and add a "test Module" to it.
  2. Using the Serializer, we serialize the collection (a Hashtable) that contains all Modules belonging to the Shell.
  3. We instantiate a new Shell object, load the state that we persisted in 2. and "enumerate" through the collection of Modules, printing to screen the instance's names.
Shell obj instance and Shell newobj instance are now in an identical state with regards to the Module collection and other serializable properties.



Conclusion

With this post, I demonstrated the concept of Java's object serialization to you. We are now able to persist and load state, which is one of the core concepts needed for our Tiniest Module Container to work. 

Stay put for more ... and yes, you will be able to access/download all of the implementation code once the project is finished.

No comments:

Post a Comment