Плагин Maven WAR и как управлять зависимостями
Хорошо, это может быть знакомый вопрос, однако я все еще смущен и изо всех сил пытаюсь найти ответ, который действительно проясняет детали.
Сценарий У меня есть несколько проектов Maven, большинство создает артефакты JAR, и один отвечает за создание артефакта WAR. Артефакт WAR имеет зависимости от артефактов JAR с областью компиляции, чтобы эти JAR-файлы были включены в папку WEB-INF/lib.
Путаница Мне все еще неясно, как этот плагин реагирует на области, относительно которых зависимости и транзитивные зависимости включаются в папку WARs lib. Насколько я понимаю, компиляция приведет к тому, что JAR будет включен вместе со своими зависимостями, которые также объявлены с областью компиляции (и т. Д. Рекурсивно), но доллар останавливается с предоставленным. Зависимость с предоставленной областью не будет включена.
Проблема Чтобы взять конкретный пример, проект WAR war-a
имеет зависимость от внутреннего проекта JAR jar-a
с областью компиляции. jar-a
будет включен в папку WARs lib из-за области действия. Сейчас jar-a
имеет зависимость от сторонней библиотеки log4j с областью компиляции. JAR log4j также включается в папку lib из-за своей области видимости. Но... так же, как и зависимости log4j, такие как почта и т. Д. Я хочу log4j, но я не хочу его зависимостей. Если я настрою log4j с предоставленным, его зависимости не будут включены, но ни один не будет сам.
Я рассмотрел варианты, такие как использование исключений, но когда имеется более 40 внутренних JAR-проектов, в файлах POM появляется много исключений. Кроме того, для использования исключений требуется, чтобы я знал конкретные знания о сторонних зависимостях, что кажется ненужным.
Может кто-нибудь уточнить, расширить, ответить на любой из вышеперечисленных? Любой вклад будет наиболее ценным.
Обновление В дополнение к вышеизложенному, я застрял с решением. Если я позволю, чтобы список требуемых сторонних JAR-файлов был объединен в WAR, необходимо разрешить его с помощью зависимостей области компиляции различных внутренних проектов Maven JAR, которые у нас есть. Или я должен объявить все сторонние зависимости, как это предусмотрено во внутренних проектах JAR Maven, а затем указать четкий набор с областью компиляции в проекте WAR Maven.
Я предпочитаю первый подход, так как дополнительные сторонние зависимости будут автоматически добавляться в артефакт WAR через транзитивные пути зависимостей. Тем не менее, второй подход обеспечивает уверенность в том, чтобы точно знать, какие сторонние библиотеки будут включены.
2 ответа
Предмет, обсуждаемый в этой документации, является ответом на мой вопрос. Обсуждается использование <dependencyManagement>
тег.
Этот тег может быть объявлен в родительском файле POM и позволяет вам указывать детали зависимостей, а также исключения. Тогда любой POM, который наследует от родительского POM, может объявить зависимость как обычно, но он унаследует любую конфигурацию от родительского, если не переопределен.
Например, возьмите родительскую конфигурацию зависимости POM:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>mail</artifactId>
</exclusion>
</exclusions>
<scope>compile</scope>
</dependency>
</dependencies>
</dependencyManagement>
Зависимость в дочернем POM теперь стала намного проще:
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
</dependencies>
Здесь дочерний POM наследует версию, исключения и конфигурацию области. Это не решает всех проблем, которые я упомянул, таких как необходимость знать о зависимостях сторонней библиотеки, но предоставляет единственное место для настройки и управления этими более мелкими деталями.
В pom.xml
из jar-a
проект исключает mail
зависимость с exclusions
тег:
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.x</version>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>mail</artifactId>
</exclusion>
</exclusions>
</dependency>
Если ваша сторонняя библиотека зависит от ненужной библиотеки, это лучшее, что вы можете сделать. Если это проекты с открытым исходным кодом, вы можете отправить патч, который удаляет ненужные библиотеки.
О "проверке на будущее": если вы хотите повторить сборку, вы должны объявить точные номера версий для ваших зависимостей, например [1.0]
что не позволяет maven обновлять их всякий раз, когда выходит новая версия. Таким образом, сторонняя библиотека никогда не изменяет свои зависимости, потому что вы не обновляетесь до новой версии, которая зависит от других библиотек. Конечно, вы должны также проверять зависимости при обновлении сторонней библиотеки на новую версию.
С другой стороны, ваши функциональные тесты должны сообщать, когда новая версия библиотеки сломала ваше приложение.
Я вижу, что с 40+ POM это не так просто, но все же проще, чем в старые времена, когда вам приходилось загружать каждую зависимость вручную.
http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html