Observability Done Right: Best Practices and Anti-Patterns for Effective System Monitoring

Image
  WHAT Observability is a concept that refers to the ability to gain insights into the behavior and performance of complex systems. In the context of software engineering, observability involves the collection, analysis, and visualization of data from software applications, infrastructure, and other components of a system. In the animal kingdom, observability plays a critical role in survival, allowing animals to monitor their surroundings, detect threats, and find food. Dolphins use echolocation to observe their surroundings. They emit high-frequency sounds that bounce off objects, allowing them to create a 3D map of their environment. Thanks for reading Knowledge Cafe! Subscribe for free to receive new posts and support my work. Subscribed WHY In today's era, architectures are becoming increasingly large, complex, and fast-paced due to the faster development and deployment of software by distributed teams with the help of DevOps, continuous delivery, and agile development methodo...

Serial Version ID in Java


This blog is continuation of earlier post on Java serialization.

Defination

Serial Version UID is used to ensure that during deserialization the same class (that was used during serialize process) is loaded. The serialVersionUID is a universal version identifier for a Serializable class. Deserialization uses this number to ensure that a loaded class corresponds exactly to a serialized object. If no match is found, then an InvalidClassException is thrown.

Serial version UID Syntax


[ANY-ACCESS-MODIFIER] static final long serialVersionUID = 123L;

 serialVersionUID is a static final field. You can assign any number of your choice to it. Later I will explain the significance of these two statements.

Why serial versionUID?


Lets start with annoying warning message you get in your IDE when you declare a class as Serializable. The serializable class Employee does  declare a static final serialVersionUID field of type long.

Most of us used to ignore this message as we always do for a warning. My general note is, always pay attention to the java warning messages. It will help you to learn a lot of fundamentals.

How serialVersionUID is generated?


serial versionUID is a 64-bit hash total  of the class name, interface class names, methods and fields. Serialization runtime generates a serialVersionUID if you do not add one in source. Refer this link for the algorithm to generate serialVersionUID.

It is advised to have serialVersionUID as unique as possible. That's why the java runtime chose to have such a complex algorithm to generate it.

If you want help in generating it, jdk tools provides a tool named serialver. Use serialver -show to start the gui version of the tool.

How serial versionUID works?

  • When an object is serialized, the serialVersionUID is serialized along with the other contents.

  • Later when that is deserialized, the serialVersionUID from the deserialized object is extracted and compared with the serialVersionUID of the loaded class.

  • If the numbers do not match then, InvalidClassException is thrown.

  • If the loaded class is not having a serialVersionUID declared, then it is automatically generated using the same algorithm as before.


Java Class to Demonstrate this concept:


Define Employee.java as below
package serializationdemo;

import java.io.Serializable;

	 class Employee implements Serializable { 

		private static final long serialVersionUID = 1L;
		private String eName;
		 private String eId;

		 public String geteName() {
			return eName;
		}

		public void seteName(String eName) {
			this.eName = eName;
		}

		public String geteId() {
			return eId;
		}

		public void seteId(String eId) {
			this.eId = eId;
		}

		Employee(String a, String b){
			 this.eName = a;
			 this.eId = b;
		 }
}

Refer  below Code to Serialize the Employee Object
package serializationdemo;
import java.io.*;

public class EmployeeSerialDemo {

	public static void main(String[] args) {
		Employee c = new Employee("Suresh", "E123"); // 2
		File outFile =  new File("empSerial.ser");	
		try {

			FileOutputStream fs = new FileOutputStream(outFile);
			ObjectOutputStream os = new ObjectOutputStream(fs);
			os.writeObject(c); // 3
			os.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

 

NewEmployeeDeserialDemo.java: This class run fine as long as serial version ID matching with Employee class. 

package serializationdemo;
import java.io.*;

public class NewEmployeeDeserialDemo {

	public static void main(String[] args) {

		File ReadFile =  new File("empSerial.ser");	
		try {
			FileInputStream fis = new FileInputStream(ReadFile);
			ObjectInputStream ois = new ObjectInputStream(fis);
			Employee e  = (Employee) ois.readObject();
			System.out.println("Deserialized Employee name= "+ e.geteName());
			System.out.println("Deserialized Employee ID= "+ e.geteId());
			ois.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

Change Employee class one line to this:

private static final long serialVersionUID = 2L;


Run NewEmployeeDeserialDemo.java again to check can we deserialized our earlier serialized object. You will get following exception:

java.io.InvalidClassException: serializationdemo.Employee; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2
	at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:604)
	at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1601)
	at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1514)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1750)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
	at serializationdemo.NewEmployeeDeserialDemo.main(NewEmployeeDeserialDemo.java:12)

Popular posts from this blog

Chain of responsibility using Spring @Autowired List

Iterate Through a HashMap

Under the Hood: Understanding the Gossip Protocol in Apache Cassandra