Maven: как переопределить зависимость, добавленную библиотекой
Вот моя общая проблема:
Мой проект P зависит от A, который зависит от B, который зависит от C, который зависит от версии 1.0.1 D.
Проблема с версией 1.0.1 из D и я хочу заставить использовать другой модуль. Я не знаю, как объявить это в моих проектах POM, так как я не добавил зависимость от D напрямую. Он C, который объявил зависимость от D.
Важно: в этом случае изменяется не только версия, но и группа и артефакт. Таким образом, это не просто вопрос переопределения версии зависимости, а, скорее, исключения модуля и включение другого.
В конкретном случае D - это StAX, у 1.0.1 есть bug. Согласно примечаниям в этой ошибке, "проблемы были решены путем замены stax-api-1.0.1 (maven GroupId = stax) на stax-api-1.0-2 (maven GroupId = javax.xml.stream)", поэтому я Я пытаюсь это сделать.
Таким образом, D = stax: stax-api: jar: 1.0.1 и C = org.apache.xmlbeans: xmlbeans: jar: 2.3.0
Я использую maven 2.0.9 в случае, если это имеет значение.
Вывод зависимости mvn: tree "
mvn dependency:tree
[..snip..]
[INFO] +- org.apache.poi:poi-ooxml:jar:3.6:compile
[INFO] | +- org.apache.poi:poi-ooxml-schemas:jar:3.6:compile
[INFO] | | +- org.apache.xmlbeans:xmlbeans:jar:2.3.0:compile
[INFO] | | | \- stax:stax-api:jar:1.0.1:compile
В моем проекте POM у меня есть следующая зависимость от "A":
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.6</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.6</version>
</dependency>
Спасибо заранее.
Ответы
Ответ 1
Просто укажите версию в текущей папке. Версия, указанная здесь, переопределит другую.
Принуждение версии
Версия всегда будет выполняться, если она объявлена в текущем POM с конкретной версией, однако следует отметить, что это также повлияет на другие poms downstream, если оно само зависит от использования транзитивных зависимостей.
Ресурсы:
Ответ 2
В качестве альтернативы вы можете просто исключить зависимость, которую вы не хотите. STAX включен в JDK 1.6, поэтому, если вы используете 1.6, вы можете просто полностью исключить его.
Мой пример ниже немного неправильный для вас - вам нужно только одно из двух исключений, но я не совсем уверен, какой из них. Существуют и другие версии плагина Stax, в моем примере ниже я импортировал A, который импортировал B, который импортировал C и D, каждый из которых (через все более транзитивные зависимости) импортировал разные версии Stax. Поэтому в моей зависимости от "A" я исключил обе версии Stax.
<dependency>
<groupId>a.group</groupId>
<artifactId>a.artifact</artifactId>
<version>a.version</version>
<exclusions>
<!-- STAX comes with Java 1.6 -->
<exclusion>
<artifactId>stax-api</artifactId>
<groupId>javax.xml.stream</groupId>
</exclusion>
<exclusion>
<artifactId>stax-api</artifactId>
<groupId>stax</groupId>
</exclusion>
</exclusions>
<dependency>
Ответ 3
У меня также возникли проблемы с перенаправлением зависимости в сторонней библиотеке. Я использовал scot-подход с исключением, но я также добавил зависимость от более новой версии в pom. (Я использовал Maven 3.3.3)
Итак, для примера stAX это будет выглядеть так:
<dependency>
<groupId>a.group</groupId>
<artifactId>a.artifact</artifactId>
<version>a.version</version>
<exclusions>
<!-- STAX comes with Java 1.6 -->
<exclusion>
<artifactId>stax-api</artifactId>
<groupId>javax.xml.stream</groupId>
</exclusion>
<exclusion>
<artifactId>stax-api</artifactId>
<groupId>stax</groupId>
</exclusion>
</exclusions>
<dependency>
<dependency>
<groupId>javax.xml.stream</groupId>
<artifactId>stax-api</artifactId>
<version>1.0-2</version>
</dependency>
Ответ 4
То, что вы положили внутри тега </dependencies>
корневой помпы, будет включено всеми дочерними модулями корневой помпы. Если все ваши модули используют эту зависимость, это путь.
Однако, если только 3 из 10 ваших дочерних модулей используют некоторую зависимость, вы не хотите, чтобы эта зависимость включалась во все ваши дочерние модули. В этом случае вы можете просто установить зависимость внутри </dependencyManagement>
. Это гарантирует, что любой дочерний модуль, который нуждается в зависимости, должен объявить его в своем собственном файле pom, но они будут использовать ту же версию этой зависимости, что указаны в тэге </dependencyManagement>
.
Вы также можете использовать </dependencyManagement>
, чтобы изменить версию, используемую в транзитивных зависимостях, потому что версия, заявленная в самом верхнем pom файле, будет использоваться. Это может быть полезно, если ваш проект A включает внешний проект B v1.0, который включает в себя другой внешний проект C v1.0. Иногда случается, что нарушение безопасности обнаруживается в проекте C v1.0, которое исправлено в версии 1.1, но разработчики B медленно обновляют свой проект, чтобы использовать v1.1 of C. В этом случае вы можете просто объявить зависимость от C v1.1 в вашем корневом корне проекта внутри `, и все будет хорошо (предполагая, что B v1.0 все еще сможет скомпилировать с C v1.1).