1. Обзор
В многомодульном проекте Maven эффективный POM является результатом слияния всех конфигураций, определенных в модуле и его родительских элементах.
Чтобы избежать избыточности и дублирования между модулями, мы часто храним общие конфигурации в общем родительском модуле. Однако может возникнуть проблема, если нам нужно иметь пользовательскую конфигурацию для дочернего модуля, не влияя на все его братья и сестры.
В этом руководстве мы узнаем, как переопределить конфигурацию родительского плагина .
2. Наследование конфигурации по умолчанию
Конфигурации плагинов позволяют нам повторно использовать общую логику сборки в проектах. Если у родителя есть плагин, у дочернего он будет автоматически без дополнительной настройки. Это как наследство.
Для этого Maven объединяет файлы XML на уровне элементов . Если дочерний элемент определяет элемент с другим значением, он заменяет элемент родительского элемента. Давайте посмотрим на это в действии.
2.1. Структура проекта
Во-первых, давайте определим многомодульный проект Maven для экспериментов. Наш проект будет состоять из одного родителя и двух детей:
+ parent
+ child-a
+ child-b
Допустим, мы хотим настроить плагин maven-compiler
для использования разных версий Java между модулями. Давайте настроим наш проект для использования Java 11 в целом, но начнем
использовать Java 8.
Начнем с родительской
конфигурации:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>11</source>
<target>11</target>
<maxmem>512m</maxmem>
</configuration>
</plugin>
Здесь мы указали дополнительное свойство maxmem
, которое также хотим использовать. Однако мы хотим, чтобы у child-a
были собственные настройки компилятора.
Итак, давайте настроим child-a
для использования Java 8:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
Теперь, когда у нас есть наш пример, давайте посмотрим, что он делает с эффективным POM.
2.2. Понимание эффективного POM
На эффективный POM влияют различные факторы, такие как наследование, профили, внешние настройки и т. д. Чтобы увидеть фактический POM, давайте запустим mvn help: Effective-pom
из каталога child-a :
mvn help:effective-pom
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<maxmem>512m</maxmem>
</configuration>
</plugin>
Как и ожидалось, child-a
имеет собственный вариант исходных
и целевых
значений. Однако еще одним сюрпризом является то, что он также имеет свойство maxmem
от своего родителя.
Это означает , что если определено какое-либо дочернее свойство, оно будет иметь преимущество, в противном случае будет использоваться родительское.
3. Расширенное наследование конфигурации
Когда мы хотим точно настроить стратегию слияния, мы можем использовать атрибуты. Эти атрибуты помещаются в XML-элемент, которым мы хотим управлять. Кроме того, они будут унаследованы и затронут только детей первого уровня.
3.1. Работа со списками
В предыдущем примере мы видели, что происходит, если дочерний элемент имеет другое значение. Теперь рассмотрим случай, когда у потомка другой список элементов. В качестве примера рассмотрим включение нескольких каталогов ресурсов с помощью плагина maven-resources-plugin .
В качестве основы давайте настроим родительский
элемент для включения ресурсов из каталога parent-resources :
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<resources>
<resource>
<directory>parent-resources</directory>
</resource>
</resources>
</configuration>
</plugin>
На этом этапе child-a
унаследует эту конфигурацию плагина от своего родителя. Однако предположим, что мы хотим определить альтернативный каталог ресурсов для child-a
:
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<resources>
<resource>
<directory>child-a-resources</directory>
</resource>
</resources>
</configuration>
</plugin>
Теперь давайте рассмотрим эффективный POM:
mvn help:effective-pom
...
<configuration>
<resources>
<resource>
<directory>child-a-resources</directory>
</resource>
</resources>
</configuration>
В этом случае весь список переопределяется дочерней конфигурацией.
3.2. Добавить родительскую конфигурацию
Возможно, мы хотим, чтобы некоторые дочерние элементы использовали общий каталог ресурсов, а также определяли дополнительные. Для этого мы можем добавить родительскую конфигурацию, используя combo.children="append"
для элемента ресурсов в родительском элементе:
<resources combine.children="append">
<resource>
<directory>parent-resources</directory>
</resource>
</resources>
Следовательно, эффективный POM будет содержать оба из них:
mvn help:effective-pom
....
<resources combine.children="append">
<resource>
<directory>parent-resources</directory>
</resource>
<resource>
<directory>child-a-resources</directory>
</resource>
</resources>
Атрибуты объединения
не распространяются ни на какие вложенные элементы. Таким образом, если бы раздел ресурсов
имел сложную структуру, вложенные элементы были бы объединены с использованием стратегии по умолчанию.
3.3. Переопределить дочернюю конфигурацию
В предыдущем примере дочерний элемент не полностью контролировал окончательный POM из-за стратегии родительского объединения. Дочерний элемент может переопределить родительский, добавив `` в свой элемент resources ,
comb.self="override"
:
<resources combine.self="override">
<resource>
<directory>child-a-resources</directory>
</resource>
</resources>
В этом случае ребенок восстанавливает контроль:
mvn help:effective-pom
...
<resources combine.self="override">
<resource>
<directory>child-a-resources</directory>
</resource>
</resources>
4. Ненаследуемые плагины
Предыдущие атрибуты подходят для тонкой настройки, но они не подходят, когда дочерний элемент полностью не согласен со своим родителем.
Чтобы избежать наследования плагина вообще, мы можем добавить свойство <inherited>false</inherited>
на родительском уровне :
<plugin>
<inherited>false</inherited>
<groupId>org.apache.maven.plugins</groupId>
...
</plugin>
Это означает, что плагин будет применяться только к родительскому элементу и не будет распространяться на его дочерние элементы.
5. Вывод
В этой статье мы увидели, как переопределить конфигурацию родительского плагина.
Во-первых, мы исследовали поведение по умолчанию. Затем мы увидели, как родитель может определить политику слияния и как потомок может ее отклонить. Наконец, мы увидели, как пометить плагин как ненаследуемый, чтобы избежать его переопределения всеми дочерними элементами.
Как всегда, код доступен на GitHub .