Quels sont les risques avec le projet Lombok ?

Lombok est une bibliothèque Java qui injecte du bytecode à la compilation pour générer les getters, setters, constructeurs, equals, hashCode et toString à partir de simples annotations. Elle supprime des centaines de lignes de boilerplate — mais son ergonomie a un coût. Ce guide fait le tour des risques avérés pour qu'une équipe décide en connaissance de cause.

Ce que Lombok fait vraiment

import lombok.Data;

@Data
public class Utilisateur {
    private String nom;
    private int age;
}

À la compilation, Lombok ajoute dans le bytecode : getters, setters, equals, hashCode, toString, et un constructeur sans argument. Côté code source, on voit 4 lignes ; côté .class, il y en a 50.

Risque 1 : dépendance à un outil qui patche le compilateur

Lombok ne génère pas de fichier Java intermédiaire. Il modifie l'AST interne du compilateur (javac) via des APIs non publiques et non supportées. Conséquences :

  • Chaque nouvelle version majeure de Java peut casser Lombok jusqu'à la publication d'un correctif (cas observé pour Java 9, 11, 16, 17, 21).
  • Les options --enable-preview ou des outils alternatifs comme Eclipse ECJ peuvent générer des incompatibilités subtiles.
  • Oracle a à plusieurs reprises signalé que la technique utilisée est fragile par design.

Risque 2 : tooling et intégration IDE

Chaque IDE a besoin du plugin Lombok pour afficher les méthodes générées, sans quoi le code apparaît rouge ("méthode inconnue"). Cela signifie :

  • Chaque nouveau développeur doit installer le plugin — IntelliJ, Eclipse, VS Code.
  • Les outils d'analyse statique (SpotBugs, PMD, SonarQube) peuvent mal interpréter le bytecode généré — ils signalent des champs non utilisés ou des null-checks manquants.
  • Les outils de couverture de test (JaCoCo) montrent parfois les méthodes générées comme non couvertes sans configuration particulière.

Risque 3 : debugging confus

Quand une erreur se produit dans un equals généré, la stack trace pointe vers une ligne qui n'existe pas dans le source. Debugger un @Builder demande une gymnastique mentale supplémentaire : il faut ouvrir le .class décompilé pour voir ce qui est réellement exécuté.

Risque 4 : subtilités des annotations

L'annotation @Data agrège cinq annotations (@Getter, @Setter, @EqualsAndHashCode, @ToString, @RequiredArgsConstructor). Les développeurs oublient parfois les conséquences :

  • @EqualsAndHashCode prend tous les champs par défaut. Pour une entité JPA, cela peut inclure des collections lazy → LazyInitializationException pendant un equals.
  • @ToString expose tout, y compris les mots de passe ou tokens, sauf si l'on ajoute explicitement @ToString.Exclude.
  • @Data rend la classe mutable (setters générés) — contre-productif pour une data class censée être immuable.

Risque 5 : complications avec la réflexion

Les frameworks qui dépendent de la réflexion (Jackson, JPA, certaines bibliothèques de mocking) peuvent avoir du mal à travailler avec des méthodes générées dont les annotations attendues manquent. Des cas documentés :

  • Jackson qui ignore des champs parce qu'un @JsonProperty sur un getter généré est perdu.
  • Mockito 5 qui refuse de mocker des classes finales générées.
  • Hibernate qui équivalent deux entités via equals généré alors qu'elles ont des IDs différents.

Risque 6 : coût de migration

Retirer Lombok d'une grosse base de code nécessite :

  1. Installer le plugin delombok de Lombok pour régénérer les classes en Java standard.
  2. Passer en revue chaque classe pour adapter les conventions (p. ex. @Builder n'a pas d'équivalent Java natif).
  3. Rejouer tous les tests.

Une sortie brutale est donc peu réaliste — mieux vaut prévenir que guérir.

Les bons usages

Malgré ces risques, Lombok reste pertinent dans certains contextes :

  • Code métier rarement modifié, où la lisibilité est le principal gain.
  • DTOs simples sans logique, où le bytecode généré a peu de chances de surprendre.
  • Prototypes ou POC.

Les alternatives modernes

Records (Java 16+)

public record Utilisateur(String nom, int age) { }

Sans dépendance externe, sans plugin IDE, avec un bytecode standard. Le compilateur génère constructeur, accesseurs, equals, hashCode et toString. La différence : les records sont immuables, ce qui est souvent un avantage. Pour des classes mutables, Java n'a pas d'équivalent direct — d'où la persistance de Lombok.

AutoValue (Google)

Plus conservateur que Lombok : génère un véritable fichier Java à la compilation, pas de patching du compilateur. Syntaxe plus verbeuse mais visible dans les IDE sans plugin.

IDE generation

IntelliJ et Eclipse génèrent equals/hashCode/toString en quelques clics. Verbose à l'écran mais 100 % standard, 100 % lisible.

Recommandation pragmatique

  1. Nouveaux projets : commencer sans Lombok. Utiliser record ou des classes explicites.
  2. Si Lombok est déjà là : rester dessus, mais éviter @Data (trop implicite), préférer les annotations ciblées (@Getter, @AllArgsConstructor).
  3. Équipe distribuée : documenter la version de Lombok et du plugin, et la tester dès chaque mise à jour de JDK.
  4. Entités JPA : ne pas mettre @Data — les collections lazy et l'identité des entités nécessitent un equals/hashCode explicite.

Lombok n'est pas diabolique — juste fragile. Utilisé avec discernement, il fait gagner du temps ; utilisé aveuglément, il finit par en coûter.