Ответ
Конфликт зависимостей — это ситуация, когда разные библиотеки (транзитивные зависимости) требуют несовместимые версии одной и той же библиотеки, и система сборки не может автоматически выбрать, какую версию использовать.
Пример в Maven POM:
<!-- Библиотека A транзитивно требует commons-lang:2.5 -->
<dependency>
<groupId>com.example</groupId>
<artifactId>lib-a</artifactId>
<version>1.0</version>
</dependency>
<!-- Библиотека B транзитивно требует commons-lang:3.0 -->
<dependency>
<groupId>com.example</groupId>
<artifactId>lib-b</artifactId>
<version>2.0</version>
</dependency>
Maven по умолчанию выберет версию, ближайшую к корню дерева зависимостей (правило "nearest definition").
Способы разрешения:
-
Явное указание версии (Maven): В секции
<dependencyManagement>или прямо в<dependency>.<dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>3.12.0</version> <!-- Форсируем конкретную версию --> </dependency> -
Исключение транзитивной зависимости (Maven):
<dependency> <groupId>com.example</groupId> <artifactId>lib-a</artifactId> <version>1.0</version> <exclusions> <exclusion> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> </exclusion> </exclusions> </dependency> -
Анализ дерева зависимостей:
mvn dependency:tree -Dincludes=commons-lang # или в Gradle gradle dependencies
В Gradle конфликты часто решаются с помощью resolutionStrategy в build.gradle.
Ответ 18+ 🔞
Да ты посмотри, какая хуйня случается! Конфликт зависимостей, ёпта! Это когда твои библиотеки, как пьяные бабы на танцполе, начинают орать каждая про свою версию одной и той же хрени. Система сборки смотрит на это безобразие и просто встаёт в ступор — какую, нахуй, версию тащить-то? Обе хотят, а они несовместимые, как кошка с собакой!
Вот смотри, как это в Maven POM выглядит, реальный пиздец:
<!-- Библиотека A тащит за собой старьё, commons-lang:2.5 -->
<dependency>
<groupId>com.example</groupId>
<artifactId>lib-a</artifactId>
<version>1.0</version>
</dependency>
<!-- А эта, сука, Библиотека B, уже требует новую, commons-lang:3.0 -->
<dependency>
<groupId>com.example</groupId>
<artifactId>lib-b</artifactId>
<version>2.0</version>
</dependency>
Maven, такой хитрожопый, по умолчанию берёт ту версию, которая в дереве зависимостей ближе всего к корню сидит. Правило "nearest definition", блядь. Но это не всегда спасает, овердохуища проблем всё равно вылазят.
Ну и как из этой жопы вылезать? А вот как, слушай сюда:
-
Впендюрить свою версию, чтоб все заткнулись (Maven): В
<dependencyManagement>или прямо в зависимость пишешь, какая тебе нужна. Все остальные — идут лесом.<dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>3.12.0</version> <!-- Вот тебе, сука, новая версия, и не спорь! --> </dependency> -
Выпилить ненужную транзитивную хрень нахуй (Maven): Говоришь одной библиотеке: "Слушай, дружок, а свой commons-lang ты оставь при себе, я свой принёс".
<dependency> <groupId>com.example</groupId> <artifactId>lib-a</artifactId> <version>1.0</version> <exclusions> <exclusion> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> </exclusion> </exclusions> </dependency> -
Сначала разобраться, кто тут вообще серит (Анализ дерева): Прежде чем рубить с плеча, посмотри, что за мудаки у тебя в проекте и кто что тянет.
mvn dependency:tree -Dincludes=commons-lang # или в Gradle, там команда своя gradle dependenciesЭто как карта местности перед боем, блядь. Без неё — слепой в жопу лезешь.
А в Gradle, там свои приколы, но тоже решаемо. Там можно в build.gradle накрутить resolutionStrategy и всем этим спорщикам мозги прописать, какую версию использовать. В общем, варианты есть, главное — не паниковать, а разбираться, что за пиздопроебибна у тебя в зависимостях творится.