Зависимость и управление
Я обычно помещаю раздел <dependencyManagement>
в parent-project/pom.xml
. Этот раздел <dependencyManagement>
содержит объявление и версию для всех зависимостей моих дочерних модулей, таких как это (то есть без элемента <scope>
):
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
</dependencies>
</dependencyManagement>
Во всех дочерних модулях (т.е. moduleX/pom.xml) у меня есть:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Очевидно, что в этом примере я повторяю <scope>test</scope>
несколько раз для одной и той же зависимости (один раз в каждом дочернем модуле, нуждающемся в junit).
Мой вопрос:
Каковы лучшие практики в отношении декларации <scope>
?
Лучше положить его в <dependencyManagement>
?
Или лучше поместить его в раздел <dependencies>
дочернего модуля (как в этом посте)? И почему?
Есть ли окончательный ответ на этот вопрос?
Ответы
Ответ 1
Немного поздно на вечеринку, но я добавлю свои два цента. Я недавно столкнулся с проблемой очень сложной для отладки. У меня есть родительский pom для управления зависимостями в нескольких проектах. Я установил его со всеми зависимостями, распространенными среди них, и включил groupId, artifactId, версию и наиболее распространенную область. Мое мышление состояло бы в том, что мне не пришлось бы включать область в раздел фактической зависимости в каждом проекте, если бы она соответствовала этой самой общей области. Проблема возникла, когда некоторые из этих зависимостей проявились как транзитивные зависимости. Например, если
- A зависит от B в области компиляции.
- B зависит от C в области компиляции
- C задано в зависимости от управляемости родительского
Тогда определяется транзитивная зависимость от C. Я не уверен, что это имеет смысл или нет, но это, конечно, сбивает с толку.
В любом случае, спасите себя от хлопот и оставляйте область вне зависимости от вашего управления.
Ответ 2
dependencyManagement
предназначен для определения версии зависимостей для всех подмодулей проекта. Единственная соответствующая область в этом разделе - import
спецификаций.
Область действия должна быть определена в разделе dependencies
.
(Для данной зависимости он определяет контекст использования. Он позволяет включать зависимость только тогда, когда она требуется для выполнения. Например, ухо не будет упаковано с зависимостями Java-ee (provided
область действия), поскольку оно найдет их на цели сервер.)
[редактировать]
У первого оператора есть исключение, область действия, provided
в разделе dependencyManagement
, переопределит определенную область в разделах dependencies
. см. DependencyManagement для определения объема
Ответ 3
Как и в случае с другими ответами, лучшая практика заключается в том, чтобы исключить область из dependencyManagement и явно указывать ее при определении зависимости. В редких случаях вам нужна другая версия одной и той же зависимости в разных областях, например, одна версия при компиляции вашего приложения и другая при ее запуске - единственный случай, о котором я могу думать, - вы хотите явно запустить свою тесты против другой версии библиотеки, если пользователи используют эту версию вместо указанной вами.
Если вы определяете область в dependencyManagement, она ограничивает использование этой версии ТОЛЬКО определенной областью - так что любые другие области получат случайную версию зависимости. Я столкнулся с этим вчера, когда мы определили junit 4.12 в dependencyManagement с областью тестирования, но наш общий модуль тестовых фреймов использовал junit с областью компиляции, поэтому вместо него взял версию 4.8.2.
Ответ 4
Нет никакой выгоды при добавлении отдельной зависимости к управлению зависимостями для любой области. Все, что у вас есть, - это дублирование. Если вы хотите, чтобы версия была настроена, добавьте свойство и используйте его в своей зависимости:
<properties>
<junit.version>4.10</junit.version>
...
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
</dependencies>
Однако есть случаи, когда управление зависимостями светит - когда вы используете boms
, чтобы упорядочить версии для больших коллекций артефактов, например, используя определенную версию реализации Java EE:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.bom</groupId>
<artifactId>jboss-javaee-6.0-with-tools</artifactId>
<version>${javaee6.with.tools.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
....