Renato Ivancic - Software Engineer

Background image

Lombok, Code Obfuscator

Backend

Lombok Logo

Lombok

Project Lombok is a Java library that automatically plugs into your editor and build tools, spicing up standard Java. It will allow you to get around the java language verbosity. It is generating byte code in the compilation process, that said it is only a build time dependency. At a runtime we don’t need it anymore. For this reason we can develop libraries with the help of Lombok and library users won’t be dependent on it.

Lombok Downsides

In 2018 I have seen this as a practical helper tool. I have been using it in simple projects for simple use-cases mostly to get rid of setters.

After years of working on different projects and with different teams I have changed my mind. I’m sure that without using Lombok one would have to write more boilerplate code in the first place, on the other hand this code would be obvious to the reader, more correct in most cases and would be compatible with other libraries and tools out of the box.

Even ChatGPT warns about its judicious use if you ask it about Lombok.

There are multiple reasons why Lombok makes code more fragile.

Insufficient Knowledge

Does every developer in the team understands Lombok tool sufficiently? It’s another tool that you have to learn and master. Do developers understand which additional code gets compiled? Do they have experience of debugging issues caused by Lombok?

Additional dependency

I have a gut feeling that 50% of bugs I have to resolve is because of dependencies in the code. For this reason I am very cautious whenever new dependency are introduced. You use the tool and later in an edge-case you find out that it’s broken and there is at best a workaround available. Or you have to wait on someone to fix the issue merge it to master and make new release. Sometimes different dependencies aren’t compatible, or you need additional configuration.

Just to bring it to the light, Lombok project has 800 opened issues in GitHub https://github.com/projectlombok/lombok.

At least it still gets new releases two or three times per year based on maven repo -> https://mvnrepository.com/artifact/org.projectlombok/lombok.

JPA

If you use @ToString Lombok annotation for you JPA entities it might cause that when you have references to other entities that are lazily loaded that the toString() method will force to load those lazy objects if @ToString isn’t customized. If toString() is then called outside the transaction it might throw LazyInitializationException or you might end up in circular dependency.

Another topic is @EqualsAndHashCode that by default might produce wrong code if your entities have autogenerated keys or are identified by a primary key.

Builder and Constructors

Lombok generated constructors might have multiple parameters and on initialization you should check their validity, while Lombok won’t provide you any additional validation.

The same is with generated Builder, it generates simple builder without your domain knowledge, it can’t provide your builder with helpful validation when it is creating a particular object. Look below on possible Builder issues with MapStruct.

Copy Pasting

I have seen many developers copy-pasting Lombok annotations to new classes just because they were used in another place in the application without consideration of this additional code is used or not.

Where to use Lombok

Based on everything mentioned above in a new project I would avoid using Lombok in the core of the service domain or its entities. I prefer this part of logic robust and transparent while Lombok often yields opposite results.

There are two cases where I would consider using Lombok:

  • I would allow myself to use Lombok in concrete implementation of DTOs in Adapters (Imagine using hexagonal architecture), e.g. in Controllers in MVC pattern or in concrete implementations of messaging adapters.
  • It might make sense to use it if your project is just a simple API Gateway or Backend for frontend type of project where your main

UtilityClass annotation

In the documentation its written “All members of a utility class are automatically marked as static. Even fields and inner classes.” But this is actually not the case with version 1.16.18. Git Lombok issue

EqualsAndHashCode exclusion

I can remember the cases where id or for example quantity field doesn’t define the equality of an entity. Maybe for your business logic it doesn’t matter if smartphone was manufactured on 13 of Friday or 24 of December, the distinction will be done by the brand, type and so on. To exclude members from equals and hashCode methods in lombok version prior you can pass the list to the @EqualsAndHashCode annotation.

@EqualsAndHashCode(exclude = {"xMember", "yMember","..."})

on the other hand you can explicitly specify in annotation which fields must be included.

@EqualsAndHashCode(of = {"xMember", "yMember","..."})

Eclipse Lombok and MapStruct

Project setup from the FAQ page of MapStruct.

When MapStruct is used with Lombok annotation processor inside of Eclipse, MapStruct annotations are not processed successfully. Be sure to use patched Lombok jar for the Eclipse IDE. Maven and IntelliJ compilation is working without issues.

Patched Lombok version provided: MapStruct github page

Builder and MapStruct

You have to be extra careful if you use Lombok generated builders as MapStruct will use them by default to generate mappers. If your classes use inheritance, and you use normal Builder it won’t create builder methods from parent class. This means MapStruct won’t be able to create mapper that sets fields from the parent class.

Sources

Lombok

#Java #Lombok