Skip to content

Instantly share code, notes, and snippets.

@rzwitserloot
Created December 5, 2020 14:33
Show Gist options
  • Save rzwitserloot/eae18aa5f77d651c0b4df7c995cdd711 to your computer and use it in GitHub Desktop.
Save rzwitserloot/eae18aa5f77d651c0b4df7c995cdd711 to your computer and use it in GitHub Desktop.
> Java+Lombok code is NOT valid Java code. Bottom line is if you remove Lombok annotations from the source code, the code will not only be not compilable but it will also be completely invalid Java. Java compiler will complain big time.
lombok ships with a delombok tool, which will convert your source code. If the concern is 'that means folks without lombok cannot write the source code', you can use that argument against upgrading java versions too which seems.. ill advised. If it's more about 'that means we can never ditch lombok' - that's not true.
> It is impossible to step-in and debug code, because the actual source code is not there.
The source code lombok generates doesn't have bugs. You can't step into a synthetic method generated by java itself either. (for example, if you have a private method, and an inner class calls that private method, java generates a package-private synthetic bridger. You cannot step into this). It's upside: You can't step into irrelevant things. You then use a setter as example - but if lombok generated the setter, that means it just sets a field, and that field is right there. You can breakpoint calls to the setter, and then observe the receiver that you are calling the setter on.
> Find Usages - For example, I want to find all the places that call a certain setter method. This is impossible to do as the method is not there.
Incorrect. For example in eclipse, to find all callers to a setter: Open the outline view, right click the setter, pick 'find all callers' from the menu.
> Refactoring - For example, I want to refactor the order of properties but the class uses @AllArgsConstructor. This is impossible to do as the constructor is not there.
Usually this works fine but there are a few refactor scripts where indeed, you'll get an error. Lombok does not generate what is explicitly there - the workaround is to write the all-args constructor out (or let eclipse generate it), then refactor, then remove it again. This is unwieldy, but compared to not using lombok at all, still superior: With lombok, for most things you won't spend the time. For a few, you do. Without lombok, you spend the time on making (and the time on maintaining) that all args constructor every time.
> By using Lombok, you’re now dependent on Lombok
This is true for every library in existence. It's less true for lombok than most, because lombok has delombok.
> Can you upgrade to a newer Java version? No, because Lombok may not support that Java version.
_Many_ libraries had some problems with the module system. Some still do. For such major upgrades, lombok is often delayed somewhat. For minor updates, that is rarely needed.
> What if Lombok ceases development in the future
This is true for every library in existence.
> Assuming you have many projects with a ton of code, when switching Lombok versions, you cannot be guaranteed that the underlying .class file did not change functionally
Lombok has an 'experimental' system in place: features for which team lombok is unwilling to commit to extensive support and backwards compatibility are released in the experimental package. This idea has now made it to java itself (preview features). Lombok tracks java (the language) itself: Backwards compatibility isn't 100% guaranteed, but near enough, and any breaks are extensively analysed, just like modern java. If you find this a serious impediment to adoption, the java ecosystem isn't for you. If instead this is a claim about trust, that's fair - but applies to every library in existence (and oracle too, of course).
> Will Jenkins be able to build?
Yes.
> Will SonarQube work with Lombok?
Yes.
> Will code style checks pass?
Yes.
> Will your code coverage tool work?
Yes. You may have to tell it about the @Generated annotation; most coverage tools support it.
> Your Java code is no longer Java.
It is. Lombok cannot run if code isn't syntactically valid java.
> From a philosophical point of view, Lombok is a hack.
That is correct.
> With Lombok, if you remove Lombok annotations, your code will NOT be valid Java code and the Java compiler will throw a ton of errors at you.
So, if you remove spring annotations, you have code that compiles, but doesn't work. With lombok, you have code that won't compile.
It seems rather weird to define 'valid code' as 'code that doesn't work at all'.
> Additionally, if Lombok is so great, why doesn’t Java (as of at least up to Java 11) have these annotations built into Java?
Many lombok features did make it to java later: `@Cleanup` showed up as try-with-resources, small parts of `@Value` made it into java's records feature.
More generally this is a 'whataboutism' fallacious arugment.
> but I don’t think this will entirely as smooth as people make it out to be,
It's hard to argue with someone's personal beliefs. This is not a verifiable or falsifiable statement.
> Will the comments be preserved after you delombok?
Yes.
> It is a big risk because if you do begin using lombok, it will become increasingly difficult to get rid of.
True for any library.
> @AllArgsConstructor - Some Lombok annotations are just bad practice.
This is disingenuous. Lombok does not force you to make this constructor. You design your API, and then lombok is there to make it easier.
For example, the common strategy to avoid an AllArgsConstructor is a builder, but that is a _TON_ of work without lombok.
Lombok makes builder easier too.
So let's make it practical: What leads to better API? It's hard to prove this, but given that builders tend to
be good API (they certainly do not suffer from the 'what if argument order is switched' issue you mentioned),
seems like the answer is: With lombok.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment