Tuesday 27 August 2013

Shallow Copy vs Deep Copy

Shallow Copy 


Shallow copy is a bit-wise copy of an object. So a new object is created that has an exact copy of the values in the original object.If any of the fields of the object are references to other object then only the reference addresses are copied.

One important Point to be Noted from the Person Class:

Person class doesn't implements Clonable interfaces so is it the reason why cloned and original object point to same Persone Object.

Points To be Noted :
  1. Changes to the cloned Person object is getting reflected in the original object as well.
  2. Changes to the direct attribute(field i.e. a) of cloned object is not updated in original object.


class Employee {

 private String name;
 private int id;
 public Employee() {}
 public Employee(int id, String name) {
  this.id = id;
  this.name = name;
 }

 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }
 @Override
 public String toString() {
  StringBuilder builder = new StringBuilder();
  builder.append("Employee [name=");
  builder.append(name);
  builder.append(", id=");
  builder.append(id);
  builder.append("]");
  return builder.toString();
 }
 public Object clone() throws CloneNotSupportedException{
  System.out.println(" Clone method of Employee Class doesn't get called ever.");
  return super.clone();
  
 }
}
Now run CloneTest class again and notice the output.Output is still the same. In fact Person class clone() method is not called at all; and hence you will not notice print statement put in its clone method.






package com.clone.example; 

public class ShallowCopyTest {
 
 public static void main(String args[]) throws CloneNotSupportedException{
  
  Employee employee = new Employee(1,"Ajay Kumar");
  Department department = new Department(1001,employee);
  System.out.println(" Department Details"+department);
  System.out.println(" Employee   Details"+department.getEmployee());

  // Shallow Cloning of Employee Object.
  
  Department department_clone_1 = (Department)department.clone();
  System.out.println(" Clone Department Details"+department_clone_1);
  
  // After cloning of Department object , Get Employee Object and made changes in properties.
  Employee employee_clone_1 = department_clone_1.getEmployee();
  employee_clone_1.setName(" Ram Kumar ");
  
  /*
   * Shallow Copy : Employee Clone Objects are point to same reference
   * of Original Employee Object so any changes get reflected to Original
   * Object of Employee. 
   *  
   */
  
  System.out.println("  Real Object  : "+ department);
  System.out.println("  Clone Object : "+ department_clone_1);
 
 }
}  

class Employee {

 private String name;

 private int id;

 public Employee() {}

 public Employee(int id, String name) {
  this.id = id;
  this.name = name;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id;
 }

 @Override
 public String toString() {
  StringBuilder builder = new StringBuilder();
  builder.append("Employee [name=");
  builder.append(name);
  builder.append(", id=");
  builder.append(id);
  builder.append("]");
  return builder.toString();
 }

 

}

class Department implements Cloneable {

 private int department;

 private Employee employee;

 public Department() {}

 public Department(int department, Employee employee) {
  this.department = department;
  this.employee = employee;
 }

 public int getDepartment() {
  return department;
 }

 public void setDepartment(int department) {
  this.department = department;
 }

 public Employee getEmployee() {
  return employee;
 }

 public void setEmployee(Employee employee) {
  this.employee = employee;
 }

 public Object clone() throws CloneNotSupportedException {
  return super.clone();

 }

 @Override
 public String toString() {
  StringBuilder builder = new StringBuilder();
  builder.append("Department [department=");
  builder.append(department);
  builder.append(", employee=");
  builder.append(employee);
  builder.append("]");
  return builder.toString();
 }

}

 
Output is : 

Department DetailsDepartment [department=1001, employee=Employee [name=Ajay Kumar, id=1]]
Employee   DetailsEmployee [name=Ajay Kumar, id=1]

Clone Department DetailsDepartment [department=1001, employee=Employee [name=Ajay Kumar, id=1]]
Real Object  : Department [department=1001, employee=Employee [name= Ram Kumar , id=1]]

Clone Object : Department [department=1001, employee=Employee [name= Ram Kumar , id=1]]


Deep Copy

A Deep Copy, copies all fields, and makes copies of dynamically allocated memory pointed to by fields. So a deep copy occurs when an object is copied along with the objects to which it refers.
So in our case deep copy will have a separate Person copy so that changes in Clone1 doesn't get reflected in Original object.

So now it's easy to understand what is a Deep Copy :



We just need to make sure that clone method creates a new copy of Person object. That's it !
package com.clone.example;

class Employee implements Cloneable {

 private String name;

 private int id;

 public Employee() {

 }

 public Employee(int id, String name) {
  this.id = id;
  this.name = name;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id;
 }

 @Override
 public String toString() {
  StringBuilder builder = new StringBuilder();
  builder.append("Employee [name=");
  builder.append(name);
  builder.append(", id=");
  builder.append(id);
  builder.append("]");
  return builder.toString();
 }

 public Object clone() throws CloneNotSupportedException {
  return super.clone();

 }

}

class Department implements Cloneable {

 private int department;

 private Employee employee;

 public Department() {

 }

 public Department(int department, Employee employee) {

  this.department = department;
  this.employee = employee;

 }

 public int getDepartment() {

  return department;

 }

 public void setDepartment(int department) {
  this.department = department;
 }

 public Employee getEmployee() {
  return employee;
 }

 public void setEmployee(Employee employee) {
  this.employee = employee;
 }

 public Object clone() throws CloneNotSupportedException {
  Department d = (Department) super.clone();
  d.employee = (Employee) employee.clone();
  return d;

 }

 @Override
 public String toString() {
  StringBuilder builder = new StringBuilder();
  builder.append("Department [department=");
  builder.append(department);
  builder.append(", employee=");
  builder.append(employee);
  builder.append("]");
  return builder.toString();
 }
}

public class DeepCopyTest {

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

  Employee employee = new Employee(1, "Ajay Kumar");
  Department department = new Department(1001, employee);
  System.out.println(" Department Details" + department);
  System.out.println(" Employee   Details" + department.getEmployee());
  // Shallow Cloning of Employee Object.

  Department department_clone_1 = (Department) department.clone();
  System.out.println(" Clone Department Details" + department_clone_1);

  // After cloning of Department object , Get Employee Object and made
  // changes in properties.
  Employee employee_clone_1 = department_clone_1.getEmployee();
  employee_clone_1.setName(" Ram Kumar ");
  /**
   * Deep Copy : So in our case deep copy will have a separate Person copy
   * so that changes in Clone1 doesn't get reflected in Original object.
   */
  System.out.println("  Real Object  : " + department);
  System.out.println("  Clone Object : " + department_clone_1);

 }

} 

Output :

Department DetailsDepartment [department=1001, employee=Employee [name=Ajay Kumar, id=1]]
Employee   DetailsEmployee [name=Ajay Kumar, id=1]
Clone Department DetailsDepartment [department=1001, employee=Employee [name=Ajay Kumar, id=1]]
Real Object  : Department [department=1001, employee=Employee [name=Ajay Kumar, id=1]]
Clone Object : Department [department=1001, employee=Employee [name= Ram Kumar , id=1]]

Friday 23 August 2013

How to exclude jars generated by maven war plugin ?

There are various way to exclude jar files generated by Maven pom file.
1. Using <packagingExcludes> tags we can exclude files.
<plugin>
  <groupid>org.apache.maven.plugins</groupid>
  <artifactid>maven-war-plugin</artifactid>
  <configuration>
   <archive>
    <manifest>
     <mainclass>com.project</mainclass>
     <addclasspath>true</addclasspath>
    </manifest>
    <manifestentries>
     <mode>development</mode>
     <url>${project.url}</url>
     <splashscreen-image>Image-Filename.png</splashscreen-image>
    </manifestentries>
   </archive>
    <packagingexcludes>WEB-INF/lib/commons*.jar,WEB-INF/lib/dom4*.jar
   </packagingexcludes>
    <webxml>${basedir}/src/main/webapp/WEB-INF/web.xml</webxml>
    <warname>finalProject</warname>
   <warsourcedirectory>src/main/webapp</warsourcedirectory>
  </configuration>
</plugin>
2. We can excluded jar base on their artifactid or groupid.
<dependency>
 <groupId>org.apache.cxf</groupId>
 <artifactId>cxf-rt-frontend-jaxws</artifactId>
 <version>${cxf.version}</version>

 <exclusions>
  <exclusion>
   <groupId>org.apache.geronimo.specs</groupId>
   <artifactId>geronimo-javamail_1.4_spec</artifactId>
  </exclusion>
 </exclusions>
</dependency>
Hidden Commands of Maven

mvn tree

view the dependency hierarchy of the project currently being built.

mvn dependency:analyze

performs byte code analysis to determine missing or unused dependencies. This goal is meant to be launched from the command line. It will fork the build and execute test-compile so there are class files to analyze. If you want to bind analyze in your pom, use the dependency:analyze-only mojo instead.