Good and Bad usage of Lombok

Lombok is a really nice tool that helps us to write less code and helps us to concentrate more on our actual work. It is more about how you use Lombok in your project. I see good and bad usage of Lombok.

What Is Lombok

Lombok is a Java library that reduces the boilerplate code in our classes. You add some annotations and Lombok generate codes for you at the compile-time. For example, if you annotate your class from the @Getter annotation then Lombok generates getter methods for all the variables in the class. 


How Lombok works

First, let us talk about how the compilation process works. There are three main steps in the process Parse and Enter, Annotation Processing, Analyse and Generate


In Parse and Ente, source files are read into a syntax tree (AST) and each tree is passed to Enter. All the annotation processors are called in the Annotation Processing step. If annotation processors generate new source or class files, the compilation process goes into the first steps and start the process again. This repeats until there are no new source or class files generated by annotation processors. AST is translated into the class file in the Analyse and Generate step.


Lombok does all the magic in the Annotation Processing step. The job of an annotation processor is to generate new source files or classes but instead, Lombok modifies the existing ones. Java compiler specification never says the annotation processors can or cannot modify the existing source file. Lombok uses this loophole to its advantage. We can modify the class that is going to generate from the source code by changing the AST. This is how Lombok words.


Why I like Lombok

Lombok makes it easy to write code by enabling us to focus only on what we suppose to do; translating business requirements into the code. Writing getters, setters, constructors, equals method or implementing builder pattern is not what we should focus on. Lombok take care of these, we just have to add suitable annotation and Lombok generate codes for us. For example, if I want to generate getters and setters I just have to annotate the class with @Getter and @Setter annotations.





If you have a complex object with many attributes you can annotate the class using @Builder annotation and Lombok will implement the builder pattern for that class. 



Here is the compiled code of the above class.



There is a lot of additional annotations that we can use in our projects to write less code like @Cleanup, @AllArgsConstructor, @Data, @Value. I have to write less code; less code means fewer things to bother about. This is great right? The above is true however Lombok does add codes into our project at the compile time, sometimes more codes than you would write.

Bad usage of Lombok

My main concern is not exactly a Lombok issue, it is how developers use Lombok in their development. Developers forget that Lombok generates codes because it is not visible in our source code.

 

The first thing most of the developers do is adding Lombok annotations into the classes before they implement anything.  For example, they annotate the DTO classes using @Data annotation to generate getters and setters. This is something that I used to do also. But the point they forget(or don't know) is that Lombok generates additional methods like equals, hashCode, toString, canEqual. But sometimes we really don't use these methods. Our code repository should not have anything that we don't use. Whatever the code we write must have a reason to exist if not we should remove it. It is the developers' responsibility to use correct Lombok annotations. The most obvious way to fix this is by adding the @Getter and @Setter annotations rather than @Data annotation. 


Some developers use Lombok to hide the Sonar violations rather than fixing them (intentionally or unintentionally). Take the below code as an example.




This constructor has nine parameters and it is a sonar violation.




Here class might be doing too many things. This should be fixed by doing the necessary code modifications. Developers use to put the @RequiredArgsConstructor to generate the constructor with the required parameters. But when they add that annotation, it drops the Sonar violation.




This is not the way to fix this Sonar violation. 



Also, I really discourage using any Lombok annotation that modifies the code. If you take @Data, @Getter, @Setter, @AllArgsConstructor adds new codes into the existing source code without modifying the code we wrote. But if you take @UtilityClass annotation it modifies our code. Take the below utility class as an example,



@UtilityClass annotation converts the existing class into a utility class by making it final and creating a private default constructor. It also changes the existing method and variables into static. If you check the above class, you will not find any issue. There are no Sonar violations also. But when you check the compiled code you will see real issues.



The value variable is a public static final variable so it should follow the constant naming convention. But when we check the source code we see it is an instance variable. Even IDE failed to identify it as a constant. One can argue that if you know how the @UtilityClass annotation works then you should know that the value variable is a constant. My main argument is that this kind of modification badly affects readability. Our code should be human-readable first. To our eyes this is an instance variable. 

Another thing we have to keep in our mind is that Lombok takes the loophole in the Java compiler specification. If Java fix this we might not be able to use Lombok. According to my tests Lombok works till java 16 ( latest version I tested).

Conclusion 

Lombok is a nice tool that help us to write less code. But we have to use it Intelligently. If we don't know how to use the Lombok we cant take the real advantage of it.
Fool with a tool is still a fool 




 


Comments

Popular posts from this blog

Docker sizing Java application

Spinnaker Authentication with Keycloak

Four Event Driven Patterns