Serialization in Java Java

What is Serialization in Java

Posted on Updated on

What is Serialization in Java

Java provides a mechanism  to convert Object into bit of Stream which includes Object data and information also Type and it’s values. Java provide automatic Serialization which required class must be implementing java.io.serialization interface.

Process of serialization is also called marshalling and in opposite reconstructing a serialization Object by extracting all fields from byte code is called as De-Serialization or unmarshalling.

Serialization is an interface that belong to java.io package which is also called as Marker class.

Marker Class :- A class that has no method and fields within it is called Marker Class. Java provides few marker class as below :

Searilizable,Cloneable,Remote,ThreadSafe interface

Where it is used :-

  • To transmit object over/across Network.
  • To buffer or in memory File system store.
  • RMI call in distributed environment.
  • Component base programming like CORBA,COM

read here about Why SerialVerisonUID is important

Key Points :-

  • transient/static type can not be serialized.
  • To extract or deserialization from series of bytes into Object may be claused in different JVM compiler if serialVersionUID is not implemented.
  • Serialization/Deserialization is a recursive process which may be cause performance footprint.

 

Example :-

  1. How to Serializated multple Object

 

How to Serialized multiple Object in Java

Posted on Updated on

 

HostPersistor.Java


import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.bean.HostInfo;

public class HostPersistor {

    static Map HostInfoMap = new Hashtable();
    public static void write(HostInfo obj) {

        FileOutputStream fout = null;
        ObjectOutputStream objout = null;
        try {
            File file = new File("HOST_SESSION_HISTORY.ser");
            if (!file.exists()) {
                file.createNewFile();
            }
            fout = new FileOutputStream(file);

            if (!HostInfoMap.containsKey(obj)) {
                HostInfoMap.put(obj.getIpaddress(),obj);
                objout = new ObjectOutputStream(fout);
                for (Map.Entry info : HostInfoMap.entrySet()) {
                    objout.writeObject(info.getValue());
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (objout != null)
                    objout.close();
                if (fout != null)
                    fout.close();

            } catch (IOException e) {
                e.printStackTrace();
            }

        }

    }

    
    private static Set readObject() {

        FileInputStream fin = null;
        ObjectInputStream objin = null;
        try {
            File file = new File("HOST_SESSION_HISTORY.ser");
            objin = new ObjectInputStream(new FileInputStream(file));
            while (true) {
                try {
                    HostInfo info = (HostInfo) objin.readObject();
                    HostInfoMap.put(info.getIpaddress(),info);
                } catch (Exception e) {
                    break;
                }

            }
        } catch (IOException e) {

        } finally {
            try {
                if (objin != null)
                    objin.close();
                if (fin != null)
                    fin.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
        return HostInfoMap.keySet();
    }

    public static Set getHostInfos() {
        return readObject();
    }

    public static List getHosts(){
        
        List list = new ArrayList();
        list.addAll(getHostInfos());
        Collections.sort(list);
        return list;
        
    }
    

    public static void main(String args[]) throws IOException {

        
        HostInfo info1 = new HostInfo("xxxx", "xx", "xxx", 22);
        HostInfo info2 = new HostInfo("aaaa", "aaaa", "aaa", 22);
        HostInfo info3 = new HostInfo("yyyyy", "yyy", "yyyy", 22);
        
        write(info1);
        write(info2);
        write(info3);
        
        for(String info : getHostInfos()){
            
            System.out.println(info);
            
        }
        
        
        //System.out.println(getHosts());
    }


    public static Map getHostInfoMap() {
        return HostInfoMap;
    }


    public static void setHostInfoMap(Map hostInfoMap) {
        HostInfoMap = hostInfoMap;
    }

}

HostInfo.Java bean which describe host information.


import java.io.Serializable;
import java.util.Stack;

/**
 * @author ajaykumar.gupta
 *
 */

public final class HostInfo implements Serializable,Comparable {

    private static final long serialVersionUID = 6243919138889562890L;

    private String ipaddress;
    private String username;
    private String password;
    private String pwd;
    private Stack cmdList = new Stack();

    private int port;
    

    public HostInfo(String ipaddress, String username, String password, int port) {

        this.ipaddress = ipaddress;
        this.username = username;
        this.password = password;
        this.port = port;
        
        cmdList.add(this.username+"@"+this.ipaddress);

    }

    public String getIpaddress() {
        return ipaddress;
    }

    public void setIpaddress(String ipaddress) {
        this.ipaddress = ipaddress;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    public Stack getCmdList() {
        return cmdList;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("HostInfo [ipaddress=");
        builder.append(ipaddress);
        builder.append(", username=");
        builder.append(username);
        builder.append(", password=");
        builder.append(password);
        builder.append(", port=");
        builder.append(port);
        builder.append(", pwd=");
        builder.append(pwd);
        builder.append(", cmdList=");
        builder.append(cmdList);
        builder.append("]");
        return builder.toString();
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((ipaddress == null) ? 0 : ipaddress.hashCode());
        result = prime * result + port;
        result = prime * result
                + ((username == null) ? 0 : username.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        HostInfo other = (HostInfo) obj;
        if (ipaddress == null) {
            if (other.ipaddress != null)
                return false;
        } else if (!ipaddress.equals(other.ipaddress))
            return false;
        if (port != other.port)
            return false;
        if (username == null) {
            if (other.username != null)
                return false;
        } else if (!username.equals(other.username))
            return false;
        return true;
    }

    @Override
    public int compareTo(HostInfo o) {
        return this.ipaddress.compareTo(o.ipaddress);
    }
    
    
    

}


 

Why SerialVerisonUID is important

Posted on Updated on

Why SerialVerisonUID is important

SerialVersionUID provides a version of Serialization class which is generated SerialVersionUID number base on class details. During deserialization process, it’s verified that sender and receiver of Serialized object version to be matched.

If  a receiver has loaded Serialized Object that has different SVUID than corresponding sender Object then it will throw an exception InvalidClassException during deserialization process.

It would be recommended to generate SerialVersionUID by eclipse or some tools.

What happened If SerialVerisionUID is not provided in Serialized Class

If SVUID is not declared in serialized Class then at run-time, compiler will calculate default serial version id base on class details. which will be defer on different Compiler specialization so it will be not guaranteed to reconstruct Serialized Object then result is unexcepted or Exception like InvalidClassException.

Therefore, to guarantee consistent SerialVersionUID across different Java compiler, it is recommended to declared explicitly SerialVersionUID in Serialization Class.

In this example we will discuss if SerialVersionUID is not implemented in serialized class then what will be happened.

Weather.Java without SerialVersionUID.


import java.io.Serializable;
public class Weather implements Serializable {

private String city;
private String temperature;

public Weather(String city, String temperature) {
this.city = city;
this.temperature = temperature;
}

public String getCity() {
return city;
}

public void setCity(String city) {
this.city = city;
}

public String getTemperature() {
return temperature;
}

public void setTemperature(String temperature) {
this.temperature = temperature;
}

@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("Weather [city=").append(city).append(", temperature=")
.append(temperature).append("]");
return builder.toString();
}

}

Here We persist a serialize Object into file system then read it. It will compile and run successfully.

because compiler generated a SerialVersionUID base on class meta data which is same through serialization and deserialization process therefore weather object is deserialized successful.


public static void main(String args[]) throws IOException, ClassNotFoundException{
Weather weather = new Weather("Delhi","42'C");

FileOutputStream fileToWrite = new FileOutputStream(new File("Weather.out"));
ObjectOutputStream objectToWrite = new ObjectOutputStream(fileToWrite);
objectToWrite.writeObject(weather);

FileInputStream fileToRead = new FileInputStream(new File("Weather.out"));
ObjectInputStream objectToRead = new ObjectInputStream(fileToRead);

System.out.println(objectToRead.readObject());

}

 

Output here :-
Weather [city=Delhi, temperature=42’C]

But suppose if serialized class “Weather” has been changed either it’s properties or SerialVersionUID then at run time compiler will load Serialize class “Weather” and calculate SVUID base on JVM compiler specification  and verify with serialized stream class object “Weather.out”. In this case compiler will found two different SVUID which cause incompatible and then generate exception as below.

Exception in thread “main” java.io.InvalidClassException: Weather; local class incompatible: stream classdesc serialVersionUID = -8353808581004792491, local class serialVersionUID = -5609001311146668266

 Add one property in Weather.java file.
private String location;

then again try to de-serialized or read the serialized Object as below :-

FileInputStream fileToRead = new FileInputStream(new File("Weather.out"));
 ObjectInputStream objectToRead = new ObjectInputStream(fileToRead);
 
 System.out.println(objectToRead.readObject());

output here :-

Exception in thread "main" java.io.InvalidClassException: Weather; local class incompatible: stream classdesc serialVersionUID = -8353808581004792491, local class serialVersionUID = -5609001311146668266
 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)
 at Weather.main(Weather.java:55)