How to create Soap Web Service in Java with Example

Hello Friends,

In this tutorial,we will learn how to create Soap based Web Services in Java language.



Before we deep dive into that,let us understand what Web Service is actually.

                  Web Service = Web + Service

Web Service as its name implies is service provided over web.

After this definition, immediate question that comes to mind is that we have lot of web sites available which provides services to its clients/users over web,so are all these web sites which provides services over web/Internet are Web Services?

Answer is NO.

Web services are created to be consumed by the applications i.e. there will be some application code which will call(consume) web service(some method of web service) to use the functionality of the web service.

Example : Say I have my web application and on the home page of my application,I want to display Weather conditions(Temperature) ,then I can call web service which expose operation(method) to fetch Weather specific data from my web application and display the data on my web application.

Web applications are for human consumption via browser.

Example : Facebook,LinkedIn,Yahoo.

Let us see below steps to create Soap based web Service :

1) Create dynamic Web Project in Eclipse by right clicking in Project explorer and then select New-> Dynamic Web Project



2)
2.1) Give any name to project ,for example "FirstWebService".
2.2) Select Target Runtime as Apache Tomcat v8.0.
Note : You can use some other version of Tomcat as well or some other Servlet container as well.
2.3) Click Finish.



3) Below is how project structure will look like in Eclipse.



4)
4.1 Create a package within src folder with name nl.blogspot.javasolutionsguide.service by right clicking on src folder and then select New -> Package.


 

4.2 Within this package create a interface with name CalculatorService by right clicking on package name and then selecting New-> Class

package nl.blogspot.javasolutionsguide.service;

/**
 * @author JavaSolutionsGuide
 *
 */
public interface CalculatorService {

}


4.3 Add methods in CalculatorService ,which will be the operations exposed by this web service or in other words these will be the operations which client/consumer of this web service can expect from this web service.

package nl.blogspot.javasolutionsguide.service;

/**
 * @author JavaSolutionsGuide
 *
 */
public interface CalculatorService {
 
 public int add(int a,int b);
 
 public int subtract(int a,int b);
 
 public int multiply(int a, int b);
 
 public int division(int a,int b);

}



4.3 Create another package within src folder with name nl.blogspot.javasolutionsguide.service.impl
4.4 Create class with name CalculatorServiceImpl which should implement CalculatorService interface.

/**
 * @author JavaSolutionsGuide
 *
 */
public class CalculatorServiceImpl implements CalculatorService{

 @Override
 public int add(int a, int b) {
  return a + b;
 }

 @Override
 public int subtract(int a, int b) {
  return a - b;
 }

 @Override
 public int multiply(int a, int b) {
  return a * b;
 }

 @Override
 public int division(int a, int b) {
  return a/b;
 }

}

5) Right click on CalculatorServiceImpl file and select Web Services -> Create Web Services




6) You will see following wizard.

As you can see,in the "web service type",we have chosen "Bottom up Java bean Web Service",which means we will create Java code having implementation first and from that we will generate contract i.e. WSDL,which then can be shared with consumer of the web service.In another approach which is "Top down Java bean Web Service" approach ,first WSDL is created and then Implementation is created.

In the Service Implementation,give the name of CalculatorServiceImpl class which we created above.
Also make sure that In the web Service section and Client type section,slider is completely on left ,which means we want to get all steps performed for web service from Develop Service -> Assemble Service -> Deploy Service ->Install Service ->Test Service  and all following steps for web service client from Develop Client -> Assemble Client -> Deploy Client -> Install Client-> Start Client ->Test Client.



7) You will get following screen,wherein you can select which methods of CalculatorServiceIm class you want to expose.By default all the methods within class will be selected as can be seen in below screenshot.Click on next,as here we will expose all methods of CalculatorServiceImpl class.



8) You will get following screen.



9) Click on Start Server.You can see message "Currently server is started" in below screen now.




10) Click on Finish.As you can see in below screenshot,a new Web Service Client project with name "FirstWebServiceClient" has been automatically created(because in Client type section in step 6 ,we had moved slider to left most ,which means we want to get client created automatically and test web service using that client) and deployed on Tomcat server along with Web service "FirstWebService".


 and as we moved slider till "Test Client" in step 6 ,browser with TestClient.jsp from Client project "FirstWebServiceClient"  is opened to test Web Service,as can be seen in below screenshot.




11)Also You will see that eclipse has added WSDL,Axis and few more jars.Here Axis is nothing but one of the implementation of java Web Services specifications.

Now What is this WSDL.

WSDL stands for Web Service Description Language.

As its name implies,this file describes web service.It tells what all methods are there in web service (calculator class in our case) and what type of input parameters they expect and what are there return types.

The Service creator needs to share this WSDL to service consumer,so that service consumer will get to know which methods of service can be called and what type of input parameter consumer needs to send and what return type they can expect.Accordingly consumer will call service methods of exposed web service.Here for example purpose,we have created both Web Service and Consumer,but in real life ,normally ,we will either be provider or consumer of the web service at a time.

12) To test web service,subtract functionality,click on subtract link in above screenshot.we will get following screen,where we can enter our inputs.


13) Enter any input to test in two text boxes and click on invoke.This will invoke web service and we will be able to see result in "Result" section as can be seen in  below screenshot.


14) If we want to debug the code of our web service,we can restart the server in Debug mode and put breakpoint in CalculatorServiceImpl's method which we  want to debug and can invoke subtract again from TestClient.jsp


15) Click on Yes,and you will be in Subtract method for debugging as below :


Thats it.With this we saw how to create Soap Web Service in Java.

Thanks for reading.Please let me know,if you face any issue during implementation.

How to migrate from Jersey 1 to Jersey 2 on Websphere

Hello Friends,

In this tutorial,we will see how to migrate from Jersey 1 to Jersey 2.

Here I am taking example of Jersey 1 version 1.18.3 and Jersey 2 version 2.23.2.

Jersey 1.18.3 dependencies 

                     <dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-bundle</artifactId>
<version>1.18.3</version>
</dependency>
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-spring</artifactId>
<version>1.18.3</version>
</dependency>
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-multipart</artifactId>
<version>1.18.3</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.9</version>
</dependency>
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-xc</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.3</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-jaxrs</artifactId>
<version>1.9.3</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.18.3</version>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<version>1.1.1</version>

</dependency>

Jersey 2.23.2 dependencies :

                       <dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<version>2.23.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-spring3</artifactId>
<version>2.23.2</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.23.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>2.23.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-entity-filtering</artifactId>
<version>2.23.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>2.23.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-common</artifactId>
<version>2.23.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.bundles.repackaged</groupId>
<artifactId>jersey-guava</artifactId>
<version>2.23.2</version>
</dependency>
<dependency>
 <groupId>org.glassfish.jersey.media</groupId>
 <artifactId>jersey-media-json-jackson</artifactId>
 <version>2.23.2</version>
 <exclusions>
 <exclusion>
 <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-annotations</artifactId>
 </exclusion>
 </exclusions>
</dependency>
<dependency>
 <groupId>com.fasterxml.jackson.core</groupId>
 <artifactId>jackson-annotations</artifactId>
 <version>2.5.4</version>
</dependency>
<dependency>
   <groupId>org.glassfish.jersey.media</groupId>
   <artifactId>jersey-media-multipart</artifactId>
   <version>2.23.2</version>
</dependency>

<dependency>
   <groupId>org.jvnet</groupId>
   <artifactId>mimepull</artifactId>
   <version>1.6</version>

</dependency>

Jersey 1.18.3 Web.xml configuration 

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<servlet>
    <servlet-name>Jersey REST Service</servlet-name>
    <servlet-class>
      com.sun.jersey.spi.spring.container.servlet.SpringServlet
    </servlet-class>
    <init-param>
      <param-name>com.sun.jersey.config.property.packages</param-name>
      <param-value>com.test.rest</param-value>
    </init-param>
    <init-param>
      <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
      <param-value>true</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Jersey REST Service</servlet-name>
    <url-pattern>/rest/*</url-pattern>
  </servlet-mapping>

  <listener>
    <listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
  </listener>

  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
    classpath:applicationContext.xml
</param-value>
  </context-param>

 <resource-ref>
    <description>DB Connection</description>
    <res-ref-name>jdbc/myAppName</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>

</web-app>

Jersey 2.23.2 Web.xml configuration 

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

<servlet>
<servlet-name>jersey-servlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.jsg.resource.initializer.RestResourceInitializer</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-servlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping> '
     
       <listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
      <resource-ref>
        <description>DB Connection</description>
        <res-ref-name>jdbc/myAppName</res-ref-name>
       <res-type>javax.sql.DataSource</res-type>
       <res-auth>Container</res-auth>
   </resource-ref>
</web-app>

RestResourceIntializer.java

package com.jsg.resource.initializer;

import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;

public class RestResourceInitializer extends Application {

/**
* Gets the classes.
*
* @return the classes
*/
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = new HashSet<Class<?>>();
 
// Resources
classes.add(org.glassfish.jersey.jackson.JacksonFeature.class);
classes.add(org.glassfish.jersey.server.spring.scope.RequestContextFilter.class);
classes.add(org.glassfish.jersey.media.multipart.MultiPartFeature.class);

               //Rest classes within Application.
                classes.add(com.jsg.rest.AbcRestService.class);

classes.add(com.jsg.rest.CdeRestService.class);
return classes;
}

}

Now if we would try to deploy this code with Jersey 2 Changes on Websphere(tried on 8.8.5),we will get following exception :

Caused by: java.lang.NoSuchMethodError: javax/ws/rs/core/Application.getProperties()Ljava/util/Map; at org.glassfish.jersey.server.ApplicationHandler.(ApplicationHandler.java:287) at org.glassfish.jersey.servlet.WebComponent.(WebComponent.java:311)

Reason for above exception is that,Websphere supports JAX-RS 1 implementation,however we are deploying Jersey 2 code which is Jax-rs 2 implementation.

How to resolve above exception 

So basically what we have to do is to force WebSphere to pick our Jersey 2 jars instead of default Jax-rs 1.We need to follow following steps for that 

1) Disable in built JAX-RS by setting following JVM property to true

    com.ibm.websphere.jaxrs.server.DisableIBMJAXRSEngine=true

   This property can be set through admin console of WebSphere by going to Servers->All Server ->  <ServerName> ->Server Infrastructure -> Java and Process Management ->Process Deifinition ->Additional Properties-> Java Virtual Machine ->Additional Properties-> Custom Properties




2) Create Isolated Shared Library having the Jersey 2 Jars and Spring 4 Jars
    Isolated shared library can be created through admin Console of Websphere by going to 
    Environment-> Shared Libraries ->New

    


   In the classpath box,we need to enter path of the folder on the server,where we have placed all        Jersey 2 and Spring 4 Jars

/var/was/server2/jerseyLib1/spring-context-4.3.4.RELEASE.jar
/var/was/server2/jerseyLib1/spring-core-4.3.4.RELEASE.jar
/var/was/server2/jerseyLib1/spring-beans-4.3.4.RELEASE.jar
/var/was/server2/jerseyLib1/spring-aop-4.3.4.RELEASE.jar
/var/was/server2/jerseyLib1/spring-web-4.3.4.RELEASE.jar
/var/was/server2/jerseyLib1/spring-expression-4.3.4.RELEASE.jar
/var/was/server2/jerseyLib1/spring-bridge-2.5.0-b05.jar
/var/was/server2/jerseyLib1/hk2-locator-2.5.0-b05.jar
/var/was/server2/jerseyLib1/hk2-api-2.5.0-b05.jar
/var/was/server2/jerseyLib1/hk2-utils-2.5.0-b05.jar
/var/was/server2/jerseyLib/javax.inject-2.5.0-b05.jar
/var/was/server2/jerseyLib1/javax.annotation-api-1.2-b03.jar
/var/was/server2/jerseyLib1/javax.ws.rs-api-2.0.1.jar
/var/was/server2/jerseyLib1/jersey-client-2.23.2.jar
/var/was/server2/jerseyLib1/jersey-spring3-2.23.2.jar
/var/was/server2/jerseyLib1/jersey-container-servlet-core-2.23.2.jar
/var/was/server2/jerseyLib1/jersey-server-2.23.2.jar
/var/was/server2/jerseyLib1/jersey-common-2.23.2.jar

/var/was/server2/jerseyLib1/jersey-guava-2.23.2.jar


Also in class loading section ,select "use an isolated class loader for this shared library"

and then finally click on Apply and Ok and we are done with creation of isolated shared library.



3. Bind this isolated shared library with your application war file as follows in admin Console

  a)  Application -> All Applications -> Click on your application name

 


  b) Go to References -> Shared Library References -> Reference Shared Libraries ->select your application war(Not ear) and click ok.


  c) Select the library that we created in Step 2 in "Available" combo box on left side and put it on right side in "Selected" combo box and click ok.



With this we have associated the isolated shared library with application war file.

4. Restart Server and application should be up and running.

Thanks for reading.Please let me know,if you have any comments,feedback or query or suggestion on this post.

Why Should we override equals method in Java

In this tutorial,we will try to understand need for overriding equals method in Java.


Let's start this topic with something very basic i.e. object.What is Object?

Anything which has state and behavior can be treated as object in Object oriented language.

State - represented by instance variables of class
behavior - represented by methods of class

For example every one of us has some state and behavior.

Our state can be represented by
- name
- address
- fatherName
- motherName

and behavior can be represented by
- eat()
- sleep()
- work()

Now if have to give a name to the Class(group) to which these objects belong,we can name it HumanBeing and class will look like as below :

package nl.blogspot.javasolutionsguide;

class HumanBeing {
 String name;
 String address;
 String fatherName;
 String motherName;

 public String getName() {
  return name;
 }

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

 public String getAddress() {
  return address;
 }

 public void setAddress(String address) {
  this.address = address;
 }

 public String getFatherName() {
  return fatherName;
 }

 public void setFatherName(String fatherName) {
  this.fatherName = fatherName;
 }

 public String getMotherName() {
  return motherName;
 }

 public void setMotherName(String motherName) {
  this.motherName = motherName;
 }

 public void eat() {
  System.out.println("Eat  like normal human beings");
 }

 public void sleep() {
  System.out.println("Sleep  like normal human beings");
 }

 public void work() {
  System.out.println("Work like normal human beings");
 }
}

Now this is general class representing all Human beings,but there are some special type of creatures in this world,who work day and night on computer to do coding and people call them Software developers,but they are human beings only,so let us create a class SoftwareDeveloper by extending HumanBeing class as below :

package nl.blogspot.javasolutionsguide;


class SoftwareDeveloper extends HumanBeing{
 
 String unit;
 String companyName;
 String technology;
 String totalExperience;
 public String getTotalExperience() {
  return totalExperience;
 }

 public void setTotalExperience(String totalExperience) {
  this.totalExperience = totalExperience;
 }
  
 public String getCompanyName() {
  return companyName;
 }

 public void setCompanyName(String companyName) {
  this.companyName = companyName;
 }

 public String getTechnology() {
  return technology;
 }

 public void setTechnology(String technology) {
  this.technology = technology;
 }

 public String getUnit() {
  return unit;
 }

 public void setUnit(String unit) {
  this.unit = unit;
 }

 public void work() {
  System.out.println("Keep Working");
 }
    
 public void eat(){
     System.out.println("Eat occasionally");
 }
    
 public void sleep(){
     System.out.println("Sleep occasionally");
 }
}

Let us now create a test Class where we will create objects of SoftwareDeveloper class and compare them.

package nl.blogspot.javasolutionsguide;

public class TestClass {

 public static void main(String[] args) {
  SoftwareDeveloper softwareDeveloper1 = new SoftwareDeveloper();
  softwareDeveloper1.setName("Gaurav");
  softwareDeveloper1.setCompanyName("ABC Limited");
  softwareDeveloper1.setTechnology("Java");
  softwareDeveloper1.setTotalExperience("8");
  softwareDeveloper1.setUnit("Fiancial Services");
  
  SoftwareDeveloper softwareDeveloper2 = new SoftwareDeveloper();
  softwareDeveloper2.setName("Gaurav");
  softwareDeveloper2.setCompanyName("ABC Limited");
  softwareDeveloper2.setTechnology("Java");
  softwareDeveloper2.setTotalExperience("8");
  softwareDeveloper2.setUnit("Fiancial Services");
  
  /*Below comparison is like saying that two physically existing 
      individuals(developer) are one and same or equal,which can never
      be the case we know.*/

  if(softwareDeveloper1 == softwareDeveloper2){
   System.out.println("Both are equally good");
  }else{
   System.out.println("Both are not equally good");
  }
  
 }
}

Output :
Both are not equally good

In the TestClass,we are creating two objects of SoftwareDeveloper class and both of them has exactly same state(properties),but still they are two different individuals,so we can not say that they are one ans same.

TakeAway 

When we compare objects using ==  it compares if they are same objects in memory and not the values (states) in the object.

What if we use equals in above TestClass to compare two SoftwareDeveloper instances


package com.test.equals;

public class TestClass {

 public static void main(String[] args) {
  SoftwareDeveloper softwareDeveloper1 = new SoftwareDeveloper();
  softwareDeveloper1.setName("Gaurav");
  softwareDeveloper1.setCompanyName("ABC Limited");
  softwareDeveloper1.setTechnology("Java");
  softwareDeveloper1.setTotalExperience("8");
  softwareDeveloper1.setUnit("Fiancial Services");
  
  SoftwareDeveloper softwareDeveloper2 = new SoftwareDeveloper();
  softwareDeveloper2.setName("Gaurav");
  softwareDeveloper2.setCompanyName("ABC Limited");
  softwareDeveloper2.setTechnology("Java");
  softwareDeveloper2.setTotalExperience("8");
  softwareDeveloper2.setUnit("Fiancial Services");
  
  if(softwareDeveloper1.equals(softwareDeveloper2)){
   System.out.println("Both are equally good");
  }else{
   System.out.println("Both are not equally good");
  }
 }
}

Output :
Both are not equally good

As we can see still,these two software developers are not being considered equal.Reason being when we are calling equals() method on SoftwareDeveloper's instance,it is actually calling equals() method in the Object class,which is parent of all java classes and by default all public methods of Object class are available to all the Java classes.Below is implementation of equals() method in Object class:

public boolean equals(Object obj) {
      return (this == obj);
}

As we can see here also,it is using == ,hence same result.

Take Away 

If we do not override equals() method in our classes,the default implementation from Object class will be available to all the classes and if we will try to compare objects using equals(),it will compare using == and will consider two objects equal only when they are referring to same object in memory.

Now one may ask,are above two approaches to compare objects is wrong?

Answer is Yes as well as No.

No,because it depends upon our requirements.if our requirements is such that we do not want to consider two different objects in memory as same even when they have same values,then there is nothing wrong with above approaches.

Yes,because there might be requirements in the application in which above code is being used that if two SoftwareDevelopers have same experience ,then consider them as equal.For example for HR department,they may give same salary to two developers with same experience ,so for them two developers with same experience are equal,although still they are two different individuals(different objects in memory).

Now one may ask,how we can make HR module of application understand that two different objects in memory are actually equal.

Answer is: we need to override equals method such that two objects should be considered equal when the value of property(instance variables) totalExperience is same.

Let us override equals() method in  SoftwareDeveloper class,such that we consider two objects equal when they have same totalExperience.

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

How above equals method is getting called 

if(softwareDeveloper1.equals(softwareDeveloper2)){
 System.out.println("Both are equally good");
}else{
 System.out.println("Both are not equally good");
}

Let us try to understand above equals method code:

if (this == obj){
    return true;
}
Here this refers to instance softwareDeveloper1 and obj refers to softwareDeveloper2 and we are comparing them with == .We are doing this first ,because if two objects are same objects in memory,obviously they are equal and there is no need to check for their values and equals method can return true in that case any ways.

if (obj == null){
   return false;
}

if we have reached inside equals method ,that means softwareDeveloper1 is definitely not null as we have invoked equals method on softwareDeveloper1 instance,but it is possible that softwareDeveloper2 will be null,in which they will not be == and hence equals should return false.

if (getClass() != obj.getClass()){
    return false;
}

getClass returns the runtime class of the object on which it is called.So here we are checking ,if softwareDeveloper1 and softwareDeveloper2 both belong to same class at runtime,if they are not belonging to same runtime class,obviously they are not equal,so equals return false.

Note : if you will print output of getClass() and obj.getClass(),you will get below :
class com.test.equals.SoftwareDeveloper
class com.test.equals.SoftwareDeveloper

SoftwareDeveloper other = (SoftwareDeveloper) obj;
if (totalExperience == null) {
   if (other.totalExperience != null)
      return false;
   } else if (!totalExperience.equals(other.totalExperience)){
     return false;
   }
   return true;
 

In above code,first we are checking whether totalExperience instance variable value of softwareDeveloper1 is null and of softwareDeveloper2 is not null.If this is the case then as totalExperience value is not equal,equals method will return false.

Next we check,if softwareDeveloper1's totalExperience is not equal to softwareDeveloper2's totalExperience ,then also equals method returns false.

And if we have crossed passed all above if,elses and equals method have not returned yet,that means totalExperience of softwareDeveloper1 and softwareDeveloper2 are equal.

Now ,after overriding equals method,if we run our TestClass code,we will get following output :

Both are equally good

Take Away :

Depending upon our functional requirements,we would like to consider two different objects in memory as equal by overriding equals method where in we can check for equality of the property(ies) of two instances and can decide whether they should be considered equal or not.

In the next tutorial we will see why we should override hashCode() method when we override equals().

Thanks for reading!!!

[Solved] validation errors for already well tested third party JavaScript libraries

Problem : Sometimes Eclipse gives validation errors for already well tested third party javascript libraries while you build your code.

Solution :

Step 1 :

Right click on the project ->Properties->JavaScript->Include path.


Step 2 : 

Select Excluded under Source tab by clicking on it.


Step 3 :

Click on Edit… button.


Step 4 :

Click on “Add Multiple…” button in Exclusion pattern section and select java script files which are giving errors and for which you don’t want  validation to happen, from Your project’s folder.
Click ok.

Step 5 :

You will see all the selected scripts in exclusion patterns as below .Click on Finish.


Step 6 : 

Click Ok on below popup.



Clean build the project again and your validation errors will be gone.

Thanks.

[Solved] There are No resources that can be added or removed from the server - Tomcat

Issue : User created a dynamic web project in Eclipse and then try to deploy it on embedded Tomcat in eclipse by right clicking on server and clicking on "Add and Remove..." option.

User gets message "There are No resources that can be added or removed from the server"

Solution :

Right click on project -> Properties->Type "Project Facets"-> Select "Project Facets" -> tick Dynamic Web Module checkbox -> Select appropriate version -> Click Apply.


Now again right click on server and select "Add and Remove..." option,you should be able to deploy project as can be seen in below screenshot.


Thanks for reading!!!!