Back to homepage

Why Lombok is hurting your code

Posted on August 10, 2021

Lombok lets you do wrong things very easily. And that is a huge problem. Using it cripples your thinking about code and its architecture.

The title of this post is very sharply phrased I know. And I would like to point out two things before I start.

The point I would like to make is that using Lombok is robbing you and your code of the benefits of well-designed code. It does it by telling you that some parts of code suck and they will always suck and there is no other way so we created a library to hide those parts out of your sight.

Here is a complete feature list but I would like to stop at only some of them which are the worst in my opinion.

Constructors

Constructors are one of the most important aspects of a class. It is a place that defines how your class fits with other classes. As in a quote "As many languages you know, as many times you are a human being" for classes it is "As many constructors class have, as many times it can be reused". A propper class has multiple constructors in order to be usable in as many contexts as possible. If your constructors just copy your fields list your problem is not "I have to write a boilerplate constructor that just copies a parameter list". The real problem here is having a class that is not reusable and that is something that Lombok won't help you with.

Builders

Builder pattern, as useful as it seems, is in most cases antipattern. Having a class with many fields is a code smell that should raise a red flag in order to make the class more composable. Of course, there are rare cases in which builders are acceptable, but they are rare, and one-time code generation in your favorite IDE is enough. Large field lists are a composition problem. Do not cover the problem under the Lombok blanket, solve the composition problem!

Getters/Setters

My favorite argument about Lombok is about getters and setters. I am often confronted with the argument that getters are boilerplate code and Lombok really helps. If you have getters and setters then sure it is. I don't face this problem so I don't need to generate them at all. I don't have getters and setters in my code. They are not needed in almost all cases. They are very hurtful to the code architecture.

In some rare cases of pure data transporter classes simple public final filed will do much better. "But I will lose the encapsulation!!". No, you won't, you can't lose something that was not there in the first place. Getters and setters actually break encapsulation in most cases. Improve your design so you dont need getters and you wont feel any need generating them.

NonNull

Having nulls in your code (not counting inputs) is a bad idea to begin with. Do not return nulls anywhere and you won't need to check for it. Return lists, null objects, throw exceptions, do anything except returning null unless there is absolutely no other way. If you don't have nulls you don't have to generate null checks.

Build time

Recently a colleague of mine discovered a big difference in a build time when using a val feature. Using it is accountable for a 63 % increase in the compilation time of our project. In our case, it is just 2 minutes. But 2 minutes times number of devs times compilations per day times working days in a year and you are at on man-year of work lost.

There are some harmless or even great features of Lombok of course. @SneakyThrows might be one of them. But those little beneficial features never pay off the technical debt introduced by ignoring the code architecture with other features.

Even a Log feature that seems harmless might not be. It sends a signal to a dev that having a statically generated logger (not injected through the constructor) is normal and a good thing. We are used to it in the Java world but I would not take it for granted. See my post about injecting a log.

Lombok takes away the reasoning about the code architecture and normalizes things that should be questioned and reasoned about.

Reject the temptation of an easy solution. Take the hard path - improving the code architecture
Taking the hard path may be slow from the begging but pays off greatly in a long run.