Welcome!

Related Topics: Java IoT

Java IoT: Article

Java Serialization - Lesson 7

Java Serialization - Lesson 7

In lessons 5 and 6 of this series you've learned how to use some of the Java streams to read or write bytes, characters or numeric data. This lesson is about reading or writing entire Java objects into streams.

Let's say your application uses a class that looks like this:

class Employee {
String lName;
String fName;
double salary;
java.util.Date hireDate;
String address;
}

Now consider the following scenario: a program HeadQuarterEmpProcessor creates an instance of the object Employee. The values of its attributes (object's state) have to be saved in a file or some other stream. Later on, another program called BranchEmpProcessor needs to recreate the instance of this object Employee in memory.

We could have done it by using one of the streams like DataOutputStream, FileWriter or others. In this case both programs would need to know a format of the saved file (data types, order of the attributes and delimiters). Luckily, Java offers a more elegant way called object serialization, which greatly simplifies the process of objects exchange.

To send the entire object to a stream a program can use the class java.io.ObjectOutputStream, while the class java.io.ObjectInputStream knows how to get an object from a stream. To serialize an object means to convert it into a set of bytes and send it to a stream. To deserialize and object means to read these bytes from a stream and recreate the instance of the received object.

How to Make a Class Serializable

To make a class serializable, just declare that this class implements the interface Serializable:

class Employee implements java.io.Serializable {
String lName;
String fName;
double salary;
java.util.Date hireDate;
String address;
}

The good news is that Serializable interface does not force you to implement any methods, that's why modification of the class Employee was minimal.

All attributes of the class Employee must have either primitive data types, or represent objects that are also serializable.

How to Serialize an Object

To serialize an object into a stream perform the following actions:

  • Open one of the output streams, for example FileOutputStream
  • Chain it with the ObjectOutputStream
  • Call the method writeObject() providing the instance of a Serializable object as an argument.
  • Close the streams

The following example performs all these steps and creates a snapshot of the object Employee in the file called NewEmployee.ser

import java.io.*;
import java.util.Date;

public class HeadQuarterEmpProcessor {

public static void main(String[] args) {
Employee emp = new Employee();
emp.lName = "John";
emp.fName = "Smith";
emp.salary = 50000;
emp.address = "12 main street";
emp.hireDate = new Date();

FileOutputStream fOut=null;
ObjectOutputStream oOut=null;

try{
fOut= new FileOutputStream("c:\\NewEmployee.ser");
oOut = new ObjectOutputStream(fOut);
oOut.writeObject(emp); //serializing employee
System.out.println(
"An employee is serialized into c:\\NewEmployee.ser");
}catch(IOException e){
e.printStackTrace();
}finally{
try {
oOut.flush();
oOut.close();
fOut.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}

If you do not want to serialize sensitive information such as salary, declare this variable using the keyword transient:

transient double salary;

The values of static and transient member variables are not serialized.

How to Deserialize an Object

To deserialize an object perform the following steps:

  • Open an input stream
  • Chain it with the ObjectInputStream
  • Call the method readObject() and cast the returned object to the class that is being deserialized.
  • Close the streams

The next example reads our file NewEmployee.ser and recreates the instance of the object Employee:

import java.io.*;

public class BranchEmpProcessor {

public static void main(String[] args) {
FileInputStream fIn=null;
ObjectInputStream oIn=null;

try{
fIn= new FileInputStream("c:\\NewEmployee.ser");
oIn = new ObjectInputStream(fIn);

//de-serializing employee
Employee emp = (Employee) oIn.readObject();

System.out.println("Deserialized " + emp.fName + " "
+ emp.lName + " from NewEmployee.ser ");
}catch(IOException e){
e.printStackTrace();
}catch(ClassNotFoundException e){
e.printStackTrace();
}finally{
try {
oIn.close();
fIn.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}

The class BranchEmpProcessor will produce the following output:

Deserialized Smith John from NewEmployee.ser

Please note that we did not explicitly created an instance of the object Employee – JVM did it for us. Make sure that definition of the class Employee is available to JVM that reads the stream. In distributed applications it usually runs on a remote machine.

During the process of deserialization all transient variables will be initialized with default values according to their type, for example integer variables will have the value of zero.

Interface Externalizable

The method writeObject() sends all attributes of an object into a stream. This could lead to unnecessary large object footprint, especially if you need to serialize the values only of some of the instance variables. Java provides Externalizable interface that gives you more control over what is being serialized and it can produce smaller object footprint. Externalizable interface is a subclass of Serializable.

This interface defines 2 methods: readExternal() and writeExternal() and you have to implement these methods in the class that will be serialized (Employee). In these methods you'll have to write code that reads/writes only the values of the attributes you are interested in. Programs that perform serialization and deserialization have to write and read these attributes in the same sequence.

The following class Employee2 serializes only the values of the last name and salary.

import java.io.ObjectOutput;
import java.io.ObjectInput;
class Employee2 implements Externalizable {
String lName;
String fName;
double salary;
java.util.Date hireDate;
String address;

public void writeExternal(ObjectOutput stream)
throws java.io.IOException {
// Serializing only salary and last name
stream.writeDouble(salary);
stream.writeUTF(lName); // String encoded in UTF-8 format
}

public void readExternal(ObjectInput stream)
throws java.io.IOException {
salary = stream.readDouble();
lName = stream.readUTF();
}

}

The class HeadQuaterEmpProcessor2 shows how to externalize the object Employee2:

import java.io.*;
import java.util.Date;

public class HeadQuarterEmpProcessor2 {

public static void main(String[] args) {
Employee2 emp = new Employee2();
emp.fName = "John";
emp.lName = "Smith";
emp.salary = 50000;
emp.address = "12 main street";
emp.hireDate = new Date();

FileOutputStream fOut=null;
ObjectOutputStream oOut=null;

try{
fOut= new FileOutputStream("c:\\NewEmployee2.ser");
oOut = new ObjectOutputStream(fOut);
emp.writeExternal(oOut); //serializing employee
System.out.println(
"An employee is serialized into c:\\NewEmployee2.ser");

}catch(IOException e){
e.printStackTrace();
}finally{
try {
oOut.flush();
oOut.close();
fOut.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}

Unlike with Serializable interface, we had to write a little more code to implement Externalizable interface, but the size of the file NewEmployee2.ser is only 21 bytes, whereas the file NewEmployee.ser has 207 bytes. First of all, we serialized the values of only two attributes, and the other reason is that files created using Externalizable interface contain data only, while files created by default Java serialization contain class metadata that include attribute names.

The next code snippet shows you how to recreate an externalized object:

fIn= new FileInputStream("c:\\NewEmployee2.ser");
oIn = new ObjectInputStream(fIn);

Employee2 emp = new Employee2();
emp.readExternal(oIn);

Serializaion in the Real World

In some types of applications you have to write the code to serialize objects, but in many cases serialization is performed behind the scenes by various server-side containers. These are some of the typical 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.

When you use serialization in time-critical applications, for example real- time stock trading systems, the size of the serialized objects should be minimal. Keep in mind that variables with longer names produce larger footprints during serialization, and this may substantially slow down your application. Think of a high volume of trade orders that is being serialized. I remember working on the application where a class TradeOrder had about a hundred member variables. After renaming the variables into meaningless v1, v2, and so on, the size of one TradeOrder instance was reduced by a thousand bytes. And we are talking about serializing of thousands orders over the network!

If performance is your primary goal, use Externalizable interface instead of Serializable. Yes, you'll have to write code to serialize each attribute, but this may speed up serialization process substantially.

While applets can connect to a remote computer using socket or RMI programming (these technologies will be explained in the future lessons of this series), HTTP protocol and such Java classes as URL and URLConnection simplify network programming. With an HTTP protocol, applets can receive or send not only a text, but also binary objects using Java Serialization.

When an EJB container decides to passivate (unload from memory) so-called stateful session bean, JVM persists its state in a safe place (usually on a disk). Later on, when this bean will be activated again, all its variables will be automatically deserialized by the EJB container.

It's not too difficult for JVM to convert a primitive integer variable into four bytes for serialization, but it's not as simple in case of classes containing variables with references to other objects. The process of converting such complex object into a sequence of bytes is called marshalling and the process of reconstructing of the objects from these bytes is called unmarshalling and Java does this job for you.

Even though we have not learned yet how to create Web applications, I still want to mention that objects used for tracking of the user sessions should be serializable, otherwise you may not be able to deploy these application in a cluster of servers.

Java serialization is a simple but powerful feature of the language, and you'll definitely will have a chance to use it in your applications.

More Stories By Yakov Fain

Yakov Fain is a Java Champion and a co-founder of the IT consultancy Farata Systems and the product company SuranceBay. He wrote a thousand blogs (http://yakovfain.com) and several books about software development. Yakov authored and co-authored such books as "Angular 2 Development with TypeScript", "Java 24-Hour Trainer", and "Enterprise Web Development". His Twitter tag is @yfain

Comments (3)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


Latest Stories
Docker and Kubernetes are key elements of modern cloud native deployment automations. After building your microservices, common practice is to create docker images and create YAML files to automate the deployment with Docker and Kubernetes. Writing these YAMLs, Dockerfile descriptors are really painful and error prone.Ballerina is a new cloud-native programing language which understands the architecture around it - the compiler is environment aware of microservices directly deployable into infra...
Apptio fuels digital business transformation. Technology leaders use Apptio's machine learning to analyze and plan their technology spend so they can invest in products that increase the speed of business and deliver innovation. With Apptio, they translate raw costs, utilization, and billing data into business-centric views that help their organization optimize spending, plan strategically, and drive digital strategy that funds growth of the business. Technology leaders can gather instant recomm...
In an age of borderless networks, security for the cloud and security for the corporate network can no longer be separated. Security teams are now presented with the challenge of monitoring and controlling access to these cloud environments, at the same time that developers quickly spin up new cloud instances and executives push forwards new initiatives. The vulnerabilities created by migration to the cloud, such as misconfigurations and compromised credentials, require that security teams t...
Blockchain has shifted from hype to reality across many industries including Financial Services, Supply Chain, Retail, Healthcare and Government. While traditional tech and crypto organizations are generally male dominated, women have embraced blockchain technology from its inception. This is no more evident than at companies where women occupy many of the blockchain roles and leadership positions. Join this panel to hear three women in blockchain share their experience and their POV on the futu...
Serverless Architecture is the new paradigm shift in cloud application development. It has potential to take the fundamental benefit of cloud platform leverage to another level. "Focus on your application code, not the infrastructure" All the leading cloud platform provide services to implement Serverless architecture : AWS Lambda, Azure Functions, Google Cloud Functions, IBM Openwhisk, Oracle Fn Project.
AI and machine learning disruption for Enterprises started happening in the areas such as IT operations management (ITOPs) and Cloud management and SaaS apps. In 2019 CIOs will see disruptive solutions for Cloud & Devops, AI/ML driven IT Ops and Cloud Ops. Customers want AI-driven multi-cloud operations for monitoring, detection, prevention of disruptions. Disruptions cause revenue loss, unhappy users, impacts brand reputation etc.
The platform combines the strengths of Singtel's extensive, intelligent network capabilities with Microsoft's cloud expertise to create a unique solution that sets new standards for IoT applications," said Mr Diomedes Kastanis, Head of IoT at Singtel. "Our solution provides speed, transparency and flexibility, paving the way for a more pervasive use of IoT to accelerate enterprises' digitalisation efforts. AI-powered intelligent connectivity over Microsoft Azure will be the fastest connected pat...
DevOps is often described as a combination of technology and culture. Without both, DevOps isn't complete. However, applying the culture to outdated technology is a recipe for disaster; as response times grow and connections between teams are delayed by technology, the culture will die. A Nutanix Enterprise Cloud has many benefits that provide the needed base for a true DevOps paradigm. In their Day 3 Keynote at 20th Cloud Expo, Chris Brown, a Solutions Marketing Manager at Nutanix, and Mark Lav...
Serverless Computing or Functions as a Service (FaaS) is gaining momentum. Amazon is fueling the innovation by expanding Lambda to edge devices and content distribution network. IBM, Microsoft, and Google have their own FaaS offerings in the public cloud. There are over half-a-dozen open source serverless projects that are getting the attention of developers.
CloudEXPO has been the M&A capital for Cloud companies for more than a decade with memorable acquisition news stories which came out of CloudEXPO expo floor. DevOpsSUMMIT New York faculty member Greg Bledsoe shared his views on IBM's Red Hat acquisition live from NASDAQ floor. Acquisition news was announced during CloudEXPO New York which took place November 12-13, 2019 in New York City.
As you know, enterprise IT conversation over the past year have often centered upon the open-source Kubernetes container orchestration system. In fact, Kubernetes has emerged as the key technology -- and even primary platform -- of cloud migrations for a wide variety of organizations. Kubernetes is critical to forward-looking enterprises that continue to push their IT infrastructures toward maximum functionality, scalability, and flexibility. As they do so, IT professionals are also embr...
BMC has unmatched experience in IT management, supporting 92 of the Forbes Global 100, and earning recognition as an ITSM Gartner Magic Quadrant Leader for five years running. Our solutions offer speed, agility, and efficiency to tackle business challenges in the areas of service management, automation, operations, and the mainframe.
The widespread success of cloud computing is driving the DevOps revolution in enterprise IT. Now as never before, development teams must communicate and collaborate in a dynamic, 24/7/365 environment. There is no time to wait for long development cycles that produce software that is obsolete at launch. DevOps may be disruptive, but it is essential. DevOpsSUMMIT at CloudEXPO expands the DevOps community, enable a wide sharing of knowledge, and educate delegates and technology providers alike.
According to the IDC InfoBrief, Sponsored by Nutanix, “Surviving and Thriving in a Multi-cloud World,” multicloud deployments are now the norm for enterprise organizations – less than 30% of customers report using single cloud environments. Most customers leverage different cloud platforms across multiple service providers. The interoperability of data and applications between these varied cloud environments is growing in importance and yet access to hybrid cloud capabilities where a single appl...
@CloudEXPO and @ExpoDX, two of the most influential technology events in the world, have hosted hundreds of sponsors and exhibitors since our launch 10 years ago. @CloudEXPO and @ExpoDX New York and Silicon Valley provide a full year of face-to-face marketing opportunities for your company. Each sponsorship and exhibit package comes with pre and post-show marketing programs. By sponsoring and exhibiting in New York and Silicon Valley, you reach a full complement of decision makers and buyers in ...