Как разрешить конфликт версий зависимостей в Maven
Что проверяют
Понимаете ли вы, по какому правилу Maven выбирает одну версию из нескольких, и умеете ли закрепить нужную осознанно. Следом обычно дают симптом: в рантайме NoSuchMethodError, хотя всё скомпилировалось, и просят рассказать, как будете искать причину.
Как отвечать
Сначала механизм. Maven не выбирает самую новую версию, как это делает Gradle. Работает правило ближайшего: побеждает версия, которая стоит ближе к вашему проекту в дереве зависимостей, а при равной глубине та, что объявлена в POM раньше. Отсюда классика: библиотеке нужен Jackson посвежее, а в сборку приезжает старый: его притащила зависимость уровнем выше.
Как искать:
mvn dependency:tree -Dverbose -Dincludes=com.fasterxml.jackson.core: показывает, кто тянет артефакт и какие версии отброшены из-за конфликта;- Maven Enforcer Plugin: правила
dependencyConvergenceиrequireUpperBoundDepsроняют сборку при расхождении версий, конфликт ловится ещё в CI.
Как чинить, от предпочтительного к крайнему:
<dependencyManagement>: закрепляет версию, в том числе для транзитивных зависимостей, во всём многомодульном проекте;- импорт BOM:
<type>pom</type>и<scope>import</scope>внутриdependencyManagement, напримерjackson-bom. Согласованный набор вместо ручного подбора; <exclusions>: убрать транзитивную зависимость у конкретного артефакта, когда она лишняя или дублирует библиотеку, переехавшую под новыйgroupId;- shading с relocation: через
maven-shade-plugin, когда двум библиотекам действительно нужны несовместимые версии.
В Spring Boot версии уже управляются родительским POM, поэтому их переопределяют свойством вроде <jackson-bom.version>, а не отдельной зависимостью.
Где спотыкаются
Уверены, что Maven берёт самую свежую версию. Это поведение Gradle, и на этой ошибке интервьюер обычно и ловит.
Лечат конфликт исключениями по всему POM. Через год никто не помнит их смысла, а одна запись в dependencyManagement решила бы то же самое в одном месте.
Поднимают версию библиотеки поверх BOM Spring Boot, не проверив совместимость. Сборка проходит, а при старте приложения летит NoSuchMethodError из соседней библиотеки.