Как происходит генерация кода Lombok на этапе компиляции и какие инструменты участвуют
Что проверяют
Понимаете ли вы, что Lombok это не рантайм-магия и не генератор отдельных файлов, а процессор аннотаций, который правит внутренние структуры javac. Из этого выводятся и его возможности, и все его проблемы: ломающиеся апгрейды JDK, необходимость плагина IDE, конфликты с другими процессорами.
Как отвечать
- Lombok регистрируется как annotation processor по JSR 269 через
META-INF/services/javax.annotation.processing.Processor, поэтому javac подхватывает его автоматически, если jar есть в classpath или вannotationProcessorPaths. - Дальше он делает то, чего стандартный API не разрешает: не создаёт новые исходники, а модифицирует AST уже компилируемых классов (
com.sun.tools.javac.tree.JCTree) между разбором и анализом. Поэтому геттеры оказываются в том же классе, а в исходнике их по-прежнему нет. - Доступ к внутренним пакетам
jdk.compilerзакрыт модульной системой, Lombok открывает их через--add-opensсам. Отсюда правило: новая версия JDK почти всегда требует свежей версии Lombok. - IDE не гоняет javac при подсветке кода, поэтому нужна поддержка плагином (в IntelliJ IDEA она встроена), иначе редактор «не видит» сгенерированные методы.
- В связке с другими процессорами важен порядок: для MapStruct нужен
lombok-mapstruct-binding.delombokразворачивает аннотации в обычный исходник, это нужно для javadoc и внешних анализаторов кода. - Для неизменяемых носителей данных современная альтернатива это
record(Java 16 и новее), Lombok там просто не нужен.
Где спотыкаются
Говорят про рефлексию в рантайме. В байткоде лежат обычные методы, никакого рантайм-компонента у Lombok нет, зависимость нужна только на компиляцию.
Называют механизм словом apt. Отдельная утилита apt удалена в JDK 8, работает Pluggable Annotation Processing API, а Lombok вдобавок выходит за его рамки.
Не могут объяснить, почему сборка падает после обновления Java, и откатывают JDK вместо обновления Lombok.
Вешают @Data на JPA-сущность: equals/hashCode считаются по всем полям, а toString подтягивает ленивые связи и роняет производительность.