
Lombok Saved My Ass - tuczi
https://devolution.tech/how-lombok-saved-my-ass/
======
lmilcin
While I can understand why somebody would want to use Lombok, this is actually
very misguided.

If you want to program in better language, just go and use better language.

The most important strength of Java and basically the only reason it is being
used is that the code is simple to understand (simplistic!), everything is
easily trace-able and debuggable and that you get fantastic tools that know
everything about code and can provide you safe operations on huge code bases
(refactoring, finding usages, tracing and understanding code paths, etc.)

Lombok and new Java features decrease reliability of tools removing Java's
biggest strength.

~~~
safaci2000
I have the complete opposite point of view. I never used @Cleanup but at least
the @Data annotation makes it much more readable IMO.

There is tons of boilerplate in a simple Java bean, so when you have 3 pages
of getters/setters, equals, hashcode, toString etc... and someone introduces
something hacky it doesn't jump out at you.

To be fair, it doesn't have to be a hack, but it's doing something weird
that's unexpected.

Then if I use @Data and I still see a Getter/Setter defined it calls it to my
attention since odds are i'm doing something different.

ie. Oh, you're parsing a string get a numeric value and then setting it with a
fallback value/exception. Okay good to know. If it screws up at least I know
there is a special behavior here.

Lombok makes these patterns much easier to read though I prefer to only use it
for repeat code. Saving one line so you can have @Cleanup doesn't seem worth
it to me. It hides too much as you said above, but it varies on the use case.

~~~
azth
> but at least the @Data annotation makes it much more readable IMO.

Record types for Java are being worked on, and we should be getting them
hopefully at some point in the (near) future.

~~~
vbezhenar
Records are strange feature. They are immutable, they can't be abstract, they
can't extend, they have implementations of some methods. I don't need anything
of that. I just need short syntax to declare property with trivial
getter/setter and that's about it. This is strange proposal.

~~~
azth
The concept of records already exists in other languages, including JVM
languages (like Scala and Kotlin). The fact that they're immutable and final
is important. If they weren't, there would be subtle bugs caused by that.
Scala actively recommends that case classes not be extended precisely due to
this fact. Overriding methods for equality and hash code make it such that
these classes can be used as keys in maps or entries in sets.

------
buremba
While I tried to use Lombok in Java 8, it never felt safe. Even if I enabled
the integration with the IDE, it magically patches my code under the hood so
it wasn't easy for me to catch the bugs introduced by Lombok.

> There is little gotcha when using Java’s try-with-resource syntax. The
> resource has to implement AutoCloseable interface, so the compiler can use
> void close() method for closing a resource. Lombok’s @Cleanup, it doesn’t
> have to implement this interface. The resource just needs to have some
> closing method which by default is void close() (but you can specify your
> own method name responsible for closing resource).

Specifically, I don't agree with this approach in a compiled language like
Java. We need to have a standard writing code in Java and AutoCloseable is the
way to go. If the library doesn't support it, just create a proxy class and
implement the interface there. It may be a bit verbose (we switched to Kotlin
later on) but it will be much easier to catch the bugs. I don't want to spend
4 hours trying to find the root cause of a strange bug in favor of writing
less code.

~~~
jillesvangurp
I used Lombok back in the day (never by choice). It's somewhat useful but I
never really liked code generation and always felt it's a bit of a kludge and
it indeed confused the hell out of intellij regularly (which is not that hard,
it gets confused all the time). It's syntactic sugar. A bit of a stop gap to
make Java look a bit more like several other decent languages out there.

Kotlin is indeed far superior and an extremely easy drop in solution on pretty
much any Java project. A lot of what Lombok tries to achieve via code
generation triggered by annotations is just built-in to Kotlin. E.g. a large
part of what Lombok does is making java beans less painful by generating
setters/getters and lots of other stuff. That's useful. However, Kotlin's data
classes are way better.

For things that are Closable/Autoclosable, Kotlin injects a use extension
function that takes a block where you use the resource and it cleans up after
you. You just do a stream.use {...} and it does the right things. Kotlin adds
tons of useful stuff like this to existing Java APIs.

Whether you use Java or Kotlin, any half decent static code analysis tool
should be able to help you spot shoddy resource handling. Same for Kotlin; it
has a lot of this built into the compiler. For Java, use spotbugs or similar.
IMHO that's not optional.

~~~
srazzaque
Agreed - lombok is a kludge for language features, but back when it was big
there weren't a lot of alternatives beyond switching to an entirely new
language and stack (a tough thing to sell in large enterprise).

Regarding IDE support - I was once on a project using Lombok where some
developers used Eclipse and others used IntelliJ. The Eclipse devs wanted to
use this new @Builder annotation, which didn't work on IntelliJ but worked
fine on Eclipse - for interesting reasons.

I attempted to patch the IntelliJ Lombok plugin to support @Builder - but gave
up on it for reasons of time, priority and the fact that I wasn't certain it
would work as Lombok continued to change. Also this was an experimental
feature at the time that wasn't even certain to become mainline. I learnt a
bit in the process.

Lombok works by passing certain switches as arguments to javac, which alters
the class files that it writes out based on the annotations. It "confused the
hell out of IntelliJ", because IntelliJ's intellisense/auto-complete plugin
ecosystem works as so: IntelliJ exposes AST _from source_ to plugins, like the
Lombok plugin, which hook in and let IntelliJ know, for instance, there's
another method here due to this annotation. So it's constant effort to ensure
the plugin's injections line up with what the compiler is actually spitting
out.

Eclipse on the other hand is always aligned. I can only infer that it
generates its autocompletion etc from the _compiler's output_. So whatever
version of Lombok you're using, the autocompletion features will always be
aligned.

~~~
dehrmann
I've used a few pojo-gen libraries, but they've never had good integrations or
workflows with IDEs, and they usually led to a flakier build. Editing the
definition file was never as good as editing a real class.

------
contingencies
Relative to toponym: a few years ago I got bitten by an unidentified creature
on the beach in Lombok and nearly died of asphyxiation due to a severe
histamine reaction and the length of time it took to get to a hospital. Really
severe .. said my goodbyes to my wife. Never had anything similar in life
before or since. Luckily we did reach hospital with a couple of minutes to
spare and the local hospital sorted it pronto (oxygen and loads of
antihistimines). The cost was minimal. Life really has its ups and downs...
too many to care about Java libraries :)

------
maxpert
So I've my self used Lombok but I've been using Kotlin lately. IMHO Kotlin if
far far superior in terms of how it provides appropriate constructs that are
patches to a stale language (hopefully new release cycle fixes it).

So far I've observed with libraries like Lombok there is a smaller community
(compared to language community) that vets the idea; and the features are
opinionated to that particular community. Which results into fragmentation;
just as example [https://immutables.github.io/](https://immutables.github.io/)
and [https://github.com/google/auto](https://github.com/google/auto) are two
libraries providing features like factories and immutable value classes. Then
you get articles like [https://codeburst.io/lombok-autovalue-and-immutables-
or-how-...](https://codeburst.io/lombok-autovalue-and-immutables-or-how-to-
write-less-and-better-code-returns-2b2e9273f877) for improving your code.

This in my opinion doesn't hurt as long as you are a small company. But when
your code is going to be used across teams with different opinions, and
language doesn't enforce a single way to define construct these kind of byte-
code mangling ideas fall apart. I've personally people complain about Lombok
and they hate it every bit. Doing these constructs at language level removes
debate, and unifies how people in larger community. I hope newer versions of
Java move fast enough to make something simple like `@Cleanup` a thing of
past. I will highly encourage everyone to try Kotlin too; it's almost
transparent drop-in with better syntax.

------
sverhagen
The irony of people telling me that they don't appreciate Spring or Hibernate
for the magic behind the annotations that they don't understand, to then turn
around and drag in Lombok. Also, if you are telling me you don't like to write
getters and setters, does that mean you are not using an IDE? _Sure_, it's a
little cumbersome to write them, but not a lot?

~~~
vbezhenar
It's easy to write them. It's hard to read them. Say I have a class with 20
properties, it means 40 methods. Now one of those methods not trivial and rest
are trivial. How can I quickly find out? I can't. Getter is 4 lines, Setter is
5 lines, 20 pairs is 180 lines of nothing.

------
marktangotango
Lombok certainly saved my wrists and hands from repetitive stress injury over
the years. Manually typing “effective java chapter 1” immutable object
implementations can be truly excruciating.

------
hn23
So you introduce a new library that does "magic" instead of using one more
line? To me this is the opposite of good code. Let alone that the given
example would probably live in some library code anyway.

~~~
ziodave
Lombok is a compile time library that doesn’t do any magic but replacing an
annotation with fragments of code. It feels more like using macros which exist
in many languages. And it helps in keeping the code readable and DRY.

~~~
hn23
So the code is inflated because the machine does the code repetition for you.
The structure of your program is not getting better I think. I do not argue
against annotations but in this case, if there is such a simple thing as try
with resources, just use it. If your code is sprinkled over with annotations
like this it is hardly getting more understandable. From my experience, a
single annotation comes often in packs.

------
jmartrican
There is a problem with JaCoCo, a Java code coverage utility, and try-with-
resources. It looks like the try-with-resources creates byte code branches
that are unreachable. In the JaCoCo report the try-with-resources line shows
up with 4 or 8 branches (I forget which) and most of them are not reachable.
That is to say, no matter what kind of unit tests you create (essentially
there are two, a test where the code throws and a test where the code does not
throw) you can not hit all the possible branches that JaCoCo detects.

This caused a problem for me because we would write very lean code with low
cyclomatic complexity and having these missed branches would screw up our code
coverage numbers, causing us to miss our standards. I would just do it the old
way, with the finally. I wish I knew about this @CleanUp. For some reason a
lot of code i am writing nowadays does not have me messing with streams
directly, but when it comes up again I will use this annotation.

~~~
eropple
_> This caused a problem for me because we would write very lean code with low
cyclomatic complexity and having these missed branches would screw up our code
coverage numbers, causing us to miss our standards._

This seems like a perverse criticism. Fix your code coverage analysis?

------
hombre_fatal

        OutputStream out = new BarOutputStream();
        in.transferTo(out);
        if (out != null) ...
    

Can someone explain how `out` could possibly be null here?

~~~
kitd
In the article, the _if_ check occurs in a _finally_ clause. So the code would
execute even if the constructor threw an exception. Hence the need to null-
check it first.

~~~
hombre_fatal
But that just isn't true. Neither finally-block appends a try-block that
initializes the stream that it null-checks.

If the `in` stream init throws, the entire try-block isn't run at all. If
`out` stream init throws, the following try/finally block isn't run either.

Lombok's docs get this wrong too. Unless I'm going crazy.

------
dehrmann
I've had better luck with patterns that take lambdas (and internally do the
try-close) because they're impossible for users to screw up.

------
swrobel
I was really hoping this was about the Indonesian island

~~~
mcqueenjordan
Lombok is named after the Indonesian island, because Java is as well.
([https://en.wikipedia.org/wiki/Java](https://en.wikipedia.org/wiki/Java))

------
mark_l_watson
I used Lombok many years ago, but stopped. Modern Lompoc, with tools like
delomboc to generate plain Java source code, and better tooling support beyond
Eclipse makes Lompoc look pretty good now (if I still used Java). Cool
project.

~~~
pojzon
What is "lompoc" coz google does not help me find it??

~~~
cs02rm0
It's a typo for lombok, I believe.

