Basic Paradigms

What is POM.xml
A Project Object Model or POM is the fundamental unit of work in Maven. It is an XML file that contains information about the project and configuration details used by Maven to build the project. It contains default values for most projects. Examples for this is the build directory, which is target. Super POM is Mavens default POM. All POMs extend the Super POM unless explicitly set

Maven works in two modes in Command Prompt –
Interactive Mode – Takes command one after another
Batch Mode – takes all command at once

Archetype – Archetype is the one which defines the type of project and project structure. i.e. mvn archetype generate
ArtifactID – Specifies the name of the project.
GroupID – Group Id is one by which similar products or components are tied together under one groupId
i.e.

org.springframework
org.apache
org.commons

If you don’t specify the package name during creation it will take the groupId as package name for classes.

Types of Repo
Remote Repo is of Two type – Internal and External

  1. Central Repo-is mavens own repo accessed over mvn.com
  2. External Repo– are those whose JARs are provided by organizations like IBM for DB2. Those JARs are initially not available in Central Repo.Paid drivers are not available in Central repo rather available in organizations repo
  3. Internal Repo-Internal repos are the one provided by working organization.The main goal of such repos are to provide stable JARs and avoiding downloads of unstable jar directly from Central or external repos and to avoid network traffic

Apart from the above we have one more repo called local repo.
Local Repo – Local repo is the one which we have in the development system under .m2 folder. Local repos would be holding old JARs even when you run clean command which does nothing more than cleaning .class files. Inorder to get rid of old JARs we need to purge

purge local repo

Other Notable Points

  1. Maven is intelligent when you run install it would instatiate before phases(validate,compile and test).When one java file is changed in the list of 100 only 1 file would be compiled rather than 100 files
  2. mvn install – will deploy the JAR fils in the local repo(local .m2 folder) where as mvn deploy(disabled by default) – will deploy the JAR in the remote repo(Internal Repo)
  3. mvn compile – will compile only the java files in the source folder not the java classes in the Test Folder
  4. The Scope of the dependency JARs would be PROVIDED incase you are planning to deploy your code in environment which has someother higher version of JAR than dev environment.The default scope is compile.Though scope is compile the JARS would be available till target container.
  5. If the Team has completed coding for release then the JAR files would be named as RELEASE (or) FINAL.If the Project is still under development than the JAR would be named as SNAPSHOTThis is to make other development team to understand that there would be still code changes accompanied with JAR.
  6. .m2 folder should not be created manually.When you create your first project(maven project) .M2 folder would be created on its own.

An artifact in maven is a resource generated by a maven project. Each maven project can have exactly one artifact like a jar, war, ear, etc.Each maven project has a unique identifier consiting of [groupId, artifactId, version]. When a maven project requires resources of another project a dependency is configured in it’s pom.xml using the above-mentioned identifier. Maven then automatically resolves the dependencies when a build is triggered. The artifacts of the required projects are then loaded either from the local repository, which is a simple directory in your user’s home, or from other (remote) repositories specified in you pom.xml.

Now the once mvn install is done the same snapshots are available in repository location as below

Two Dimensional Arrays (Array of Arrays)

 //Seating Arrangement for 20 Seats
 int arrSeating[][] = new int[4][5];

 //No of Items Produced in Hr By Days in Month
 int arrProdHrByDaysInMonth[][] = new int[30][24];

Two Dimensional Arrays(Array of Arrays of Arrays)

 //No of Items Produced in Hr By Days in Month by Month
 int arrProdHrByDaysInMonth[][][] = new int[12][30][24];

Jagged Arrays
array of arrays such that member arrays can be of different sizes

Looping through ArrayList

         	//Iterate over Collection
		for (Iterator iterator = arrNames.iterator(); iterator.hasNext();) {
			String object = (String) iterator.next();
			System.out.println(object);
		}			
		
		//Iterate over array or Collection
		for (String string : arrNames) {
			System.out.println(string);
		}		
		
		//Iterate over array 
		for (int i = 0; i < arrNames.size(); i++) {
			System.out.println(arrNames.get(i));
		}
		
		//Iterate over array using Temporary Variable
		for (int i = 0; i < arrNames.size(); i++) {
			String string = arrNames.get(i);
			System.out.println(string);
		}

Which one of the Above method is Faster?
All the methods are of same speed since the Traditional for loop uses Iterator inside.The performance difference is noted when there is change in data structure while doing random access like linkedlist is slower than arraylist when you use a traditional for loop since to traverse a 6th element in list it should start from all again

When there is a sorted Array and you should do a search in the sorted array then using BinarySearch is faster than Linear Search

Simple Singleton Using ENUM

MySingleton.java

public enum MySingleton {
  INSTANCE;   
}

Enum Classes has Private Constructor by Default

The Above code can be explicitly written as

MySingleton.java

public enum MySingleton {
    public final static MySingleton INSTANCE = new MySingleton();
    private MySingleton() {
    }
}

When your code first accesses INSTANCE, the class MySingleton will be loaded and initialized by the JVM. This process initializes the static field above once (lazily).

Why cant enum constructors be protected or public in Java?
Enums as a class with a finite number of instances. There can never be any different instances beside the ones you initially declare.Thus, you cannot have a public or protected constructor, because that would allow more instances to be created.

  1. Place the Cursor in Line and press Ctrl + R while Debugging instead of using Breakpoints to get the Control over the line

Ideal Debug Perspective Setup

Options in Debug Perspective
Inspect, Display, Execute, Watch

When you added some file as JAR file and do a Debug then the Debug Stack Trace will try to go through code which doesn’t have source attached to it. In such case we can use step filtering to let debugger know files which needs to be skipped while debugging.

In the below code I try to reach for the Constructor StringUtil.But when I try to do so by pressing F5 it throws ClassNotFoundException since the class need to be loaded first time into JVM

ClassNotFoundException

Now I use Step Filer to Skip Debugger going through classes in JRE by Using StepFilter

Window -> Preferences -> Java|Debug|Step Filtering.

Now I check Java.* to make sure I skips JRE code which does class loading into JVM.

Now when I start Debug again It directly Takes me into StringUtil

We can also add other classes through which we don’t want our debugger to flow its control by Creating your own step filters as below

  1. Window > Preferences > Java > Debug > Step Filtering.
  2. Click Add Filter
  3. Enter a regular expression for the classes you want to filter in the Pattern to filter field
  4. Few custom filters as below
    • org.apache.*
    • org.hibernate.*
    • com.google.*
    • org.eclipse.*
    • org.osgi.*

The whole concept of serialization works on versioning. If you save a class object using one version of the class but attempt to deserialize using a newer or different version of the class deserialization might fail.

When you class structure can change in between you serialize the instance and go again to de-serialize it. Changed structure of class will cause JVM to give exception while de-serializing process.This problem can be solved only by adding a unique serial version id to class. It will prevent the compiler to throw the exception by telling that both classes are same, and will load the available instance variables only.

The serialization runtime associates with each serializable class a version number, called a serialVersionUID, which is used during deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect to serialization. If the receiver has loaded a class for the object that has a different serialVersionUID than that of the corresponding sender’s class, then deserialization will result in an InvalidClassException. A serializable class can declare its own serialVersionUID explicitly by declaring a field named “serialVersionUID” that must be static, final, and of type long

 static final long serialVersionUID = 69L;

If a serializable class does not explicitly declare a serialVersionUID, then the serialization runtime will calculate a default serialVersionUID value for that class based on various aspects of the class, as described in the Java(TM) Object Serialization Specification

While Implementing Singleton the following things should be answered

  1. Reflection
  2. Serialization
  3. Cloning

Objects for Singleton Classes implemented using private Constructor can be invoked by Reflection as below

Item3.java

package com.mugil.org.ej;

import java.lang.reflect.Constructor;

public class Item3 {
	public static void main(String[] args) 
	{
		// reflection concept to get constructor of a Singleton class.  
		Constructor<Singleton> constructor;
		
		try {			
			constructor = Singleton.class.getDeclaredConstructor();
			
			// change the accessibility of constructor for outside a class object creation.
			constructor.setAccessible(true);
			
			// creates object of a class as constructor is accessible now.
			Singleton secondOb = constructor.newInstance();
			System.out.println(secondOb.getName());
			
			// close the accessibility of a constructor.
			constructor.setAccessible(false);
		} catch (Exception e){
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
	}
}


class Singleton {

    private static Singleton instance = new Singleton();

    /* private constructor */
    private Singleton() {}

    public static Singleton getDefaultInstance() {
        return instance;
    }
    
    public String getName()
    {
    	return "MyName";
    }
}

Output

MyName

Singleton and Serialization
Without readResolve() Method

// Java code to explain effect of 
// Serilization on singleton classes
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.Serializable;
 
class Singleton implements Serializable 
{
    // public instance initialized when loading the class
    public static Singleton instance = new Singleton();
     
    private Singleton() 
    {
        // private constructor
    }
}
 
 
public class GFG 
{
 
    public static void main(String[] args) 
    {
        try
        {
            Singleton instance1 = Singleton.instance;
            ObjectOutput out
                = new ObjectOutputStream(new FileOutputStream("file.text"));
            out.writeObject(instance1);
            out.close();
     
            // deserailize from file to object
            ObjectInput in 
                = new ObjectInputStream(new FileInputStream("file.text"));
             
            Singleton instance2 = (Singleton) in.readObject();
            in.close();
     
            System.out.println("instance1 hashCode:- "
                                                 + instance1.hashCode());
            System.out.println("instance2 hashCode:- "
                                                 + instance2.hashCode());
        } 
         
        catch (Exception e) 
        {
            e.printStackTrace();
        }
    }
}

Output

instance1 hashCode:- 1550089733
instance2 hashCode:- 785945

With readResolve() Method

// Java code to remove the effect of 
// Serialization on singleton classes
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.Serializable;
 
class Singleton implements Serializable 
{
    // public instance initialized when loading the class
    public static Singleton instance = new Singleton();
     
    private Singleton() 
    {
        // private constructor
    }
     
    // implement readResolve method
    protected Object readResolve()
    {
        return instance;
    }
}
 
public class GFG 
{
 
    public static void main(String[] args) 
    {
        try
        {
            Singleton instance1 = Singleton.instance;
            ObjectOutput out 
                = new ObjectOutputStream(new FileOutputStream("file.text"));
            out.writeObject(instance1);
            out.close();
         
            // deserailize from file to object
            ObjectInput in 
                = new ObjectInputStream(new FileInputStream("file.text"));
            Singleton instance2 = (Singleton) in.readObject();
            in.close();
         
            System.out.println("instance1 hashCode:- "
                                           + instance1.hashCode());
            System.out.println("instance2 hashCode:- "
                                           + instance2.hashCode());
        } 
         
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

Output

instance1 hashCode:- 1550089733
instance2 hashCode:- 1550089733

Refer https://codethataint.com/blog/singleton-and-serialization/

// JAVA code to explain cloning 
// issue with singleton
class SuperClass implements Cloneable
{
  int i = 10;
 
  @Override
  protected Object clone() throws CloneNotSupportedException 
  {
    return super.clone();
  }
}
 
// Singleton class
class Singleton extends SuperClass
{
  // public instance initialized when loading the class
  public static Singleton instance = new Singleton();
 
  private Singleton() 
  {
    // private constructor
  }
}
 
public class GFG
{
  public static void main(String[] args) throws CloneNotSupportedException 
  {
    Singleton instance1 = Singleton.instance;
    Singleton instance2 = (Singleton) instance1.clone();
    System.out.println("instance1 hashCode:- "
                           + instance1.hashCode());
    System.out.println("instance2 hashCode:- "
                           + instance2.hashCode()); 
  }
}

Output

Output :- 
instance1 hashCode:- 366712642
instance2 hashCode:- 1829164700

Two different hashCode means there are 2 different objects of singleton class.

To overcome this issue, override clone() method and throw an exception from clone method that is CloneNotSupportedException. Now whenever user will try to create clone of singleton object, it will throw exception and hence our class remains singleton.

// JAVA code to explain overcome 
// cloning issue with singleton
class SuperClass implements Cloneable
{
  int i = 10;
 
  @Override
  protected Object clone() throws CloneNotSupportedException 
  {
    return super.clone();
  }
}
 
// Singleton class
class Singleton extends SuperClass
{
  // public instance initialized when loading the class
  public static Singleton instance = new Singleton();
 
  private Singleton() 
  {
    // private constructor
  }
 
  @Override
  protected Object clone() throws CloneNotSupportedException 
  {
    throw new CloneNotSupportedException();
  }
}
 
public class GFG
{
  public static void main(String[] args) throws CloneNotSupportedException 
  {
    Singleton instance1 = Singleton.instance;
    Singleton instance2 = (Singleton) instance1.clone();
    System.out.println("instance1 hashCode:- "
                         + instance1.hashCode());
    System.out.println("instance2 hashCode:- "
                         + instance2.hashCode()); 
  }
}

Output

Output:-
Exception in thread "main" java.lang.CloneNotSupportedException
	at GFG.Singleton.clone(GFG.java:29)
	at GFG.GFG.main(GFG.java:38)

If you don;t want to throw exception you can also return the same instance from clone method.

// JAVA code to explain overcome 
// cloning issue with singleton
class SuperClass implements Cloneable
{
  int i = 10;
 
  @Override
  protected Object clone() throws CloneNotSupportedException 
  {
    return super.clone();
  }
}
 
// Singleton class
class Singleton extends SuperClass
{
  // public instance initialized when loading the class
  public static Singleton instance = new Singleton();
 
  private Singleton() 
  {
    // private constructor
  }
 
  @Override
  protected Object clone() throws CloneNotSupportedException 
  {
    return instance;
  }
}
 
public class GFG
{
  public static void main(String[] args) throws CloneNotSupportedException 
  {
    Singleton instance1 = Singleton.instance;
    Singleton instance2 = (Singleton) instance1.clone();
    System.out.println("instance1 hashCode:- "
                           + instance1.hashCode());
    System.out.println("instance2 hashCode:- "
                           + instance2.hashCode()); 
  }
}

Output

Output:-
instance1 hashCode:- 366712642
instance2 hashCode:- 366712642

The Best way to implement Singleton is by using ENUM which takes care of Serialization and Other Issues on its own.

Singleton.java

public class Singleton 
{ 
    private static Singleton instance;   
 
    private Singleton() {}

    public static Singleton getInstance() 
    {
       if (instance == null) {
          instance = new Singleton();
       }
       return instance;
    }
}

In a Multi-threaded Environment

  1. Two Threads, Thread A and Thread B tries to access Object of Singleton class
  2. Thread A and B does call to Static getInstance() method
  3. Now when Thread A tries to do Null Check of instance instance == null chances of Thread B also entered the if block exists
    .
    .
    .
    if (instance == null) 
    {
      //Two threads may have passed the condition and might have got in
      instance = new Singleton();
    }
    .
    .
    .
    
  4. Now both the Threads have their own instance for the Singleton class.
  5. So there would be 2 instances of Singleton class at the end of if Block

Now there are many work arounds but DoubleCheckedLocking, Enum Singleton and Initialization On Demand Holder are the Optimized approach

Refer Table in Link

Method 1
In this method we does static block initialization of Singleton along with synchronized getInstance() method which allows the access to only one thread at a point of time.
Singleton.java

public class Singleton 
{
    private static Singleton instance;
 
    private Singleton() {}

    public static synchronized Singleton getInstance() 
    {
       if (instance == null) {
          instance = new Singleton();
       }
       return instance;
    }
}

But the above method is expensive since there is unnecessary locking and unlocking done every time the object get accessed.

Method 2(Double Checked Locking Singleton)
Instead of synchronizing the whole method lets synchronize the block of code which allows single thread to access the instance during the first time access.The consecutive thread would be served with the same thread allocated for the First thread once it is done with its task.

Singleton.java

public class Singleton 
{
    private volatile static Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() 
    {
      if (instance == null) {
          synchronized(Singleton.class) {
             if (instance == null) {
                instance = new Singleton();
             }
          }
       }
       return instance;
    }
}

Other ways of achieving singleton are by using Eager Initialization and ENUM which has its own advantages and disadvantages.

In which scenario we should serialize a singleton?
Imagine you have a long-running app and want to be able to shut it down and later continue at the point where it was shut down (e.g. in order to do hardware maintenance). If the app uses a singleton that is stateful, you’d have to be able to save and restore the sigleton’s state, which is most easily done by serializing it.

Is it possible to serialize a singleton object?
2 Methods

  1. By using ENUM : ENUM implements Serializable by Default
  2. By adding implements Serializable to class to make it serializable, and delaring all instance fields transient (to prevent a serialization attack) and provide a readResolve method.

readResolve() method in Singleton Class implementing Serialization

.
.
// readResolve method to preserve singleton property
private Object readResolve() {
     // Return the one true Elvis and let the garbage collector
     // take care of the Elvis impersonator.
    return INSTANCE;
}
.
.

Why you need readResolve() Method
This method will be invoked when you will de-serialize the object. Inside this method, you must return the existing instance to ensure single instance application wide.

The Way serialization works is as below

Serializes the Object Property -> Stores to Persistent Storage
From Persistent Storage -> Creates new Object and Sets Properties of Object

The Object Before Serialization and after Serialization are not same. Only the Object Properties are same

Now lets take a simple Example where we serializes the PrintReport Class which has priority as one of its Object Variable.priority tells which should be given first preference while printing

PrintReport.java

package com.mugil.org;

import java.io.Serializable;

public class PrintReport implements Serializable {
    private static PrintReport instance = null;
	 
    public static PrintReport getInstance() {
        if (instance == null) {
            instance = new PrintReport();
        }
        return instance;
    }
    
    private transient int priority = 2;

	public int getPriority() {
		return priority;
	}
	
	public void setPriority(int priority) {
		this.priority = priority;
	}
}

Now when the above singleton which implements serialization gets called as below

PrintMedicalReport.java

package com.mugil.org;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;

public class PrintMedicalReport 
{	
	 static PrintReport instanceOne = PrintReport.getInstance();
	 
	    public static void main(String[] args) {
	        try {
	            // Serialize to a file
	            ObjectOutput out = new ObjectOutputStream(new FileOutputStream(
	                    "filename.ser"));
	            out.writeObject(instanceOne);
	            out.close();
	            
	            instanceOne.setPriority(1);
	            
	            // Serialize to a file
	            ObjectInput in = new ObjectInputStream(new FileInputStream(
	                    "filename.ser"));
	            PrintReport instanceTwo = (PrintReport) in.readObject();
	            in.close();
	 
	            System.out.println(instanceOne.getPriority());
	            System.out.println(instanceTwo.getPriority());
	 
	        } catch (IOException e) {
	            e.printStackTrace();
	        } catch (ClassNotFoundException e) {
	            e.printStackTrace();
	        }
	    }
}

Output

1
2

Note in the above code the instanceOne.setPriority(2); should have been called before out.writeObject(instanceOne).But that is not the case since the example explains the Object are different before and after Serialization.Only Object Properties(Metadata) are stored during serialization not the actual object.

You can see the Class Prints default Priority value in the output.

Now in context to singleton we want to maintain exactly one Object exist before and after serialization. Not with two object with same set of attributes.To achieve this we add readResolve() Method.

PrintReport.java

package com.mugil.org;

import java.io.Serializable;

public class PrintReport implements Serializable {
	private volatile static PrintReport instance = null;
	 
    public static PrintReport getInstance() {
        if (instance == null) {
            instance = new PrintReport();
        }
        return instance;
    }
    
    private int priority = 1;

	public int getPriority() {
		return priority;
	}
	
	public void setPriority(int priority) {
		this.priority = priority;
	}    
	     
    protected Object readResolve() {
        return instance;
    }   
}

Now when the PrintMedicalReport class gets executed the Output would be as below

Output

1
1

When you Serialize and Deserialize new file would be created and stored in disk every time.

In the above image by changing the filename.ser text you can change the attribute of objects serialized. This is known as Serialization attack. To overcome this you must declare all instance fields as transient.

Reference 2