java, libraries

Lombok – A must have library to spice up your Java

Java, unfortunately, does have a lot of unwanted verbosity when it comes to creating classes. Whilst there are new languages on jvm competing with each other by having to write very less amount of boilerplate code, java still is not even close to these competitors.

While we sit and complain about the language’s inability to incorporate reduction of unwanted ceremony of code, ProjectLombok, has given us a work around to make our lives a little bit easier.

Alright, I am a Java programmer about to write a simple model class for my CRUD operations. I will have to go thru the following steps to create the model.

  1. Create the model-class.
  2. Define the attributes for the model with right scope. (Since its good practice to encapsulate attributes properly, I will have to set the access specifier to private. Personally I’m not a big fan of this).
  3. Create default constructor and parameterized-constructors based on my needs.
  4. Optionally, I also have to override toString(), equals() and hashCode() if needed.
  5. If I am done with the above stuff, I might think of have a nice builder pattern if needed, so that I can have a fluid way to populate the attributes.

This has to be repeated and could sometimes be a very painful thing, if we have to do it for many models and, things for sure will get annoying if the model class has to change. Clearly, we don’t have to do such things in modern languages like scala or groovy or kotlin. These languages give you getters, setters, etc., for free. It would be awesome if java would also come up with something like this to avoid unnecessary boilerplate code when instantiating classes. Well, Lombok exactly solves this thing for us. It silently generates all the boiler plate code by integrating with the build tool and also the IDE for you to focus just on specifying what you need and the business logic.

If you look at the above steps we followed to create a model class, except creating the class and the attributes (which we have to anyway in any language) everything else, starting from specifying access specifier, creating getters and setters for the same, having to override bunch of obvious methods could be avoided and Lombok provides an awesome way to achieve this thru annotations.

Below is a model where I used Lombok annotations in the Spring-Integration post.


package com.indywiz.springorama.springintegration.model;
import javax.persistence.Entity;
import javax.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
@Data
@Entity
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Person {
@Id
private Long personId;
private String personName;
private String personPhoneNumber;
}

view raw

Person.java

hosted with ❤ by GitHub

This is a very simple model where I have just three fields, couple of JPA annotations and a bunch of Lombok annotations. The interesting thing to see is what Lombok generated for me when compiling the class.


package com.indywiz.springorama.springintegration.model;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class Person {
@Id
private Long personId;
private String personName;
private String personPhoneNumber;
public static Person.PersonBuilder builder() {
return new Person.PersonBuilder();
}
public Long getPersonId() {
return this.personId;
}
public String getPersonName() {
return this.personName;
}
public String getPersonPhoneNumber() {
return this.personPhoneNumber;
}
public void setPersonId(Long personId) {
this.personId = personId;
}
public void setPersonName(String personName) {
this.personName = personName;
}
public void setPersonPhoneNumber(String personPhoneNumber) {
this.personPhoneNumber = personPhoneNumber;
}
public boolean equals(Object o) {
if (o == this) {
return true;
} else if (!(o instanceof Person)) {
return false;
} else {
Person other = (Person)o;
if (!other.canEqual(this)) {
return false;
} else {
label47: {
Object this$personId = this.getPersonId();
Object other$personId = other.getPersonId();
if (this$personId == null) {
if (other$personId == null) {
break label47;
}
} else if (this$personId.equals(other$personId)) {
break label47;
}
return false;
}
Object this$personName = this.getPersonName();
Object other$personName = other.getPersonName();
if (this$personName == null) {
if (other$personName != null) {
return false;
}
} else if (!this$personName.equals(other$personName)) {
return false;
}
Object this$personPhoneNumber = this.getPersonPhoneNumber();
Object other$personPhoneNumber = other.getPersonPhoneNumber();
if (this$personPhoneNumber == null) {
if (other$personPhoneNumber != null) {
return false;
}
} else if (!this$personPhoneNumber.equals(other$personPhoneNumber)) {
return false;
}
return true;
}
}
}
protected boolean canEqual(Object other) {
return other instanceof Person;
}
public int hashCode() {
int PRIME = true;
int result = 1;
Object $personId = this.getPersonId();
int result = result * 59 + ($personId == null ? 43 : $personId.hashCode());
Object $personName = this.getPersonName();
result = result * 59 + ($personName == null ? 43 : $personName.hashCode());
Object $personPhoneNumber = this.getPersonPhoneNumber();
result = result * 59 + ($personPhoneNumber == null ? 43 : $personPhoneNumber.hashCode());
return result;
}
public String toString() {
return "Person(personId=" + this.getPersonId() + ", personName=" + this.getPersonName() + ", personPhoneNumber=" + this.getPersonPhoneNumber() + ")";
}
public Person() {
}
public Person(Long personId, String personName, String personPhoneNumber) {
this.personId = personId;
this.personName = personName;
this.personPhoneNumber = personPhoneNumber;
}
public static class PersonBuilder {
private Long personId;
private String personName;
private String personPhoneNumber;
PersonBuilder() {
}
public Person.PersonBuilder personId(Long personId) {
this.personId = personId;
return this;
}
public Person.PersonBuilder personName(String personName) {
this.personName = personName;
return this;
}
public Person.PersonBuilder personPhoneNumber(String personPhoneNumber) {
this.personPhoneNumber = personPhoneNumber;
return this;
}
public Person build() {
return new Person(this.personId, this.personName, this.personPhoneNumber);
}
public String toString() {
return "Person.PersonBuilder(personId=" + this.personId + ", personName=" + this.personName + ", personPhoneNumber=" + this.personPhoneNumber + ")";
}
}
}

view raw

Person.java

hosted with ❤ by GitHub

This is how the class would have looked if I had to write class manually without Lombok. With just 24 lines of code with Lombok, I get getters and setters, builder pattern, a constructor with all the three attributes, a default constructor and a toString() method that appends all the toString() of the class attributes. I could have gotten a lot more, by just adding bunch more Lombok annotations.

Installing Lombok:

Installing lombok is very straight-forward. You need to let the IDE and the build-tool know that you are using Lombok. Rest is all done for you by lombok.

Letting the IDE know:

  1. Download the Lombok jar from here.
  2. Either double-click on the downloaded jar file or run the following command from the location where you downloaded jar.
    java -jar lombok.jar
  3. Lombok will automatically scan your system to find the IDE installations and ask you permission to install Lombok plugin automatically for you. If it was not able to find the installations in their default locations, you also can specify the location where you have installed your IDE too. Screen Shot 2018-04-22 at 6.53.24 PM
  4. Then click on Install button and you are set.

Letting your build tool know:

For maven:

Add the following dependency to your pom file.


<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
<scope>provided</scope>
</dependency>
</dependencies>

For gradle:

Add the following to your build.gradle file.


lombok {
version = 1.16.20
sha256 = ""
}

And you are all set to use Lombok in your development environment. May you have all the power that Lombok annotations brings forth. To know what other annotations that Lombok offers take a look at the official documentation here.

Standard