I'm interested in the downsides of using Lombok, since the article seems to only focus on its positives and makes it seem like I should download it and start using it right now.
Is there anyone here with Lombok experience that wants to share any issues they've run into while using it? All I can think of right now is the fact that the source code isn't compatible with Java.
> Project Lombok hooks itself into the compilation process as an annotation processor. But Lombok is not your normal annotation processor... The trick is that Lombok modifies the AST. It turns out that changes made to the AST in the Annotation Processing phase will be visible to the Analyse and Generate phase. Thus, changing the AST will change the generated class file.
That said, we never encountered any Lombok-related problems when running services in the cloud or locally. And the Lombok plugin for IntelliJ is good enough in that the auto-complete will "see" the Lombok-modified version of the file. For example, using the @Value annotation creates an immutable value type, which among other things a) makes every field private and final, and b) generates a getter method for each now-private field. With the Lombok plugin, IntelliJ auto-complete will a) not auto-complete the composed fields which are now private, and b) auto-complete the generated getter methods.
I highly recommend looking past the voodoo bytecode manipulation and using Lombok. The @Value annotation alone is worth the price of admission and made me a more productive programmer.
Oops! My mistake – you are absolutely correct. Lombok was just so pervasively used in our services, I assumed it came included as part of the Dropwizard toolbox.
Yeah, I use it at a financial services client. A previous architect chose it because it was a pet project of his (he contributed to Delombok).
The premise is fine...I have no problem with it. But the default generation of @EqualsAndHashcode literally pulls in the WORLD to generate the output.
The real world scenario we had was this. Lots of POJOs were created, many were simply but a non-trivial number were NOT. Those POJOs could have dozens and dozens of fields. And if you have a key abstraction with say, 86 fields, things get interesting.
Suppose you don't use @EqualsAndHashCode on one of these POJOS with lots of fields, ALL 86 fields are included in the default equals and hashCode methods. They didn't realize this, or didn't care, and as a result, had some serious performance issues because trying to run hashCode on insert to a map when you're hashing 86 fields together might actually take some time inserting 100,000 records... ugh
So in short, it's OK and useful, but you have to understand the side effects of everything to know if it's the right thing for you.
SIDE NOTE: A POJO with 86 fields can be common in financial services when you are representing various kinds of financial trades where gazillions of things are tracked on them...interest rates of note, ratings, security characteristics, etc. That in and of itself isn't necessarily poor design, although these choices predated me at this company.
I have a /really/ hard time believing you wouldn't factor out a couple of POJO's from those properties that belong together and include them to compose your classes. Sounds more like sloppy data modeling.
I dislike Lombok. One reason I dislike it is that it makes IDE navigation, even with a required Lombok plugin, more difficult. A common task in a Java IDE is finding usages. It's harder with Lombok. Generally it's just more friction than plain Java code.
I also don't like that the generated code is not checked in or visible. It makes code review harder. In theory you can have magic change to all Lombok classes just by upgrading the library.
Also it doesn't pass the cost/benefit test for me. Adding Lombok adds complexity to your code, build system, and IDE. What do you get? Slightly shorter classes? Less characters? Most of this code can be generated by the IDE.
I'll give Lombok one win. It will keep equals and hashcode up to date if you add properties. That's a pretty common error.
As others have said, Kotlin is the best alternative. But even without Kotlin I skip Lombok happily.
If you check in generated code, you have to prevent anyone from editing it (so it doesn't become something you have to start testing and reviewing) and include some kind of summary so nobody wastes time looking at it.
The downside is that you'll need to install it into your IDE. And again when you upgrade it. I guess the version needs to loosely match the one your projects use too. That might not sound like a lot but some colleagues hate that overhead.
I love it though, think I've been using it for at least 8 years now in just about every Java project.
> The downside is that you'll need to install it into your IDE. And again when you upgrade it. I guess the version needs to loosely match the one your projects use too.
If you work on a lot of different projects with different versions of Lombok, do you have to have multiple versions of the IDE plugin installed / is that even possible?
The @Builder annotation has some odd behavior if you want to add default values (it just hardcodes them and you cannot override them!) or extra builder methods.
Actually, anything involving default values seems to be very brittle and difficult to work with -- especially when deserializing objects from JSON.
The @Wither annotation results in methods that do not always make a copy, and sometimes use == instead of .equals when comparing class members. If you call one of the Wither methods and assume you have a copy of the original object, and then you modify that "copy", you might have just created a very subtle bug.
If you are using IntelliJ you can use the Refactor > Delombok menu option to show you the code that Lombok generates. I've been told that does not actually invoke the same code that the annotation processor invokes at compile time, so the results of Delombok might be misleading.
Yeah, but what if I want to build an object with @Value on it, which makes all variables final, and I want to specify a default value to be used only if the user does not provide one to the builder? That's not possible.
A builder is just a fancy alternative to a constructor. It is possible to set the value of a final field in a constructor, and it is also possible to have another constructor in the same object that sets a default value for that field. I expect the same flexibility from a builder.
For example:
public class Person {
private final String name;
public Person(String name) {
this.name = name;
}
public Person() {
this("Bob");
}
}
Now you can get immutable Person objects:
Person p1 = new Person();
Person p2 = new Person("some other name");
But if you do this with Lombok:
@Value
@Builder
public class Person {
@Builder.Default("Bob")
private String name;
}
You cannot do this:
Person p = Person.builder().name("Some other name").build();
The name is stuck at the Builder.Default value. In that sense it is not a default, rather it is the only possible value. A default is supposed to be something that can be overridden.
I could use @Data instead of @Value but then the resulting Person objects would be mutable which I don't want.
One of the issues is that it's tied quite heavily to the Java compiler, so you may need to wait until Lombok supports a new Java version before you can use it.
Also as it is compiler magic, it can be a bit confusing to developers who haven't used it before.
I've heard it makes Kotlin integration a pain also if you are ever planning on that. If your Kotlin code depends on Java lombok classes, the compiler fails. Most people probably don't have this concern, but IMHO a mixed Kotlin-Java project is better than any of the current 'data class' libraries available for Java (Lombok, Immutables, Joda-Beans, AutoValue) ... ymmv, and I'm eager to see what comes of the "data classes in java proposal".
You get a more complex (and slower) build. Poorer editor support. It may be hard to upgrade Java version (ie. going from 8 to 11). More string for developers to hang in. I wouldn't use it.
The only downside I've come across was test coverage tools like jacoco can have problems with the auto-generated code (complaining about your tests not covering enough branches of an auto-generated hashCode() implementation, for example). However it seems new-ish versions of jacoco seem to have built support for it.
Just recently removed Lombok from one of our projects.
1. To use it you have to use plugin for each IDE. If project not frequently used, spending time for each developer here doesn't make any sense.
2. Another reason was, person who used Lombok abused all OOP principles. Project became a book of anti-patterns.
Is there anyone here with Lombok experience that wants to share any issues they've run into while using it? All I can think of right now is the fact that the source code isn't compatible with Java.