Maven2 - проблема с подключением pluginManagement и parent-child
из maven документация
pluginManagement: это элемент, который отображается вдоль боковых плагинов. Плагин управления содержит элементы плагина почти таким же образом, за исключением того, что вместо того, чтобы настраивать информацию плагина для этой конкретной сборки проекта, он предназначен для настройки сборных проектов, которые наследуются от этого. Тем не менее, это только настраивает плагины, которые на самом деле ссылаются на элемент плагинов в дочерних элементах. Дети имеют полное право переопределять определения pluginManagement.
Теперь: если у меня это в родительском POM
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.0</version>
<executions>
Some stuff for the children
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
и я запускаю mvn help: effective-pom в родительском проекте Я получаю то, что хочу, а именно часть плагинов непосредственно в сборке (тот, кто делает работу) остается пустым.
Теперь, если я делаю следующее:
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.0</version>
<executions>
Some stuff for the children
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<inherited>true</inherited>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
mvn help: effective-pom Я снова получаю то, что хочу, плагины содержат только то, что объявлено, и раздел pluginManagement игнорируется.
НО изменение с помощью следующих
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.0</version>
<executions>
Some stuff for the children
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.0</version>
<inherited>false</inherited> <!-- this perticular config is NOT for kids... for parent only -->
<executions>
some stuff for adults only
</execution>
</executions>
</plugin>
</plugins>
</build>
и запустить mvn help: effective-pom
материал из раздела pluginManagement добавляется поверх того, что уже объявлено. как таковой:
<build>
<pluginManagement>
...
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.0</version>
<inherited>false</inherited> <!-- this perticular config is NOT for kids... for parent only -->
<executions>
Some stuff for the children
</execution>
<executions>
some stuff for adults only
</execution>
</executions>
</plugin>
</plugins>
</build>
Есть ли способ исключить часть для детей из родительского раздела pom? Фактически, я хочу, чтобы pluginManagement вел себя точно так, как указано в документации, то есть я хочу, чтобы он применялся только для детей, но не для проекта, в котором он объявлен.
Как механизм, есть ли способ переопределить части из pluginManagement, объявив плагин в разделе нормального построения проекта? что бы я ни пытался, я понял, что раздел добавлен к выполнению, но я не могу переопределить тот, который уже существует.
EDIT:
Я никогда не нашел приемлемого решения для этого, и поэтому проблема остается открытой. Ближайшее решение было предложено ниже и в настоящее время является принятым решением для этого вопроса, пока не появится что-то лучшее. Прямо сейчас есть три способа добиться желаемого результата (модулировать поведение плагина в зависимости от того, где в иерархии наследования находится текущий POM):
1 - используя профили, он будет работать, но вы должны остерегаться того, что профили не наследуются, что несколько противоречит интуиции. Они (если активированы) применяются к POM, где объявлено, и затем этот сгенерированный POM распространяется вниз. Таким образом, единственный способ активировать профиль для дочернего POM определенно в командной строке (по крайней мере, я не нашел другого способа). Свойство, файл и другие средства активации не могут активировать POM, потому что триггер не находится в POM, где объявлен профиль.
2 - (это то, что я закончил делать) Объявите плагин как не унаследованный в родительском и повторно объявите (скопируйте-вставить) лакомый кусочек в каждом ребенке, где он нужен. Не идеально, но это просто и работает.
3 - Разделите характер агрегации и родительский характер родительского POM. Затем, поскольку часть, которая применяется только к родительскому объекту, находится в другом проекте, теперь возможно использовать pluginManagement, как и предполагалось. Однако это означает, что должен быть создан новый искусственный проект, который не вносит вклад в конечный продукт, а служит только системе can. Это явный случай концептуального кровотечения. Также это относится только к моим конкретным и трудно обобщить, поэтому я отказался от усилий, чтобы попытаться сделать эту работу в пользу некрасивого, но более содержащего патча и патча, описанного в 2.
Если кто-то, сталкивающийся с этим вопросом, имеет лучшее решение либо из-за моего незнания Maven, либо потому, что инструмент развился, чтобы разрешить это, разместите решение здесь для справок в будущем.
Спасибо вам за помощь: -)
Ответы
Ответ 1
Добавление конфигурации плагина в pluginManagement означает, что эта конфигурация будет использоваться, если объявлен плагин, но вам все равно нужно объявить плагин в секции сборки любого POM, который хочет его использовать.
Ключевая часть, которая объясняет это из раздела, который вы указали:
Однако это только настраивает плагины, которые на самом деле ссылаются на элемент плагинов в дочерних
Итак, если вы сделаете это в дочерней папке, будет применена конфигурация родителя:
<build>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
</plugin>
</plugins>
</build>
Обновление. Чтобы ответить на фактический вопрос, контент из раздела pluginManagement всегда сливается с любым объявлением плагина. Чтобы избежать этого, вы можете определить раздел pluginManagement в профиле и активировать этот профиль в дочерних проектах, но не родительский. Затем дочерние проекты должны были объявить этот профиль.
Например:
<profiles>
<profile>
<id>for-children</id>
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.0</version>
<executions>
<!--Some stuff for the children-->
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
</profiles>
<build>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.0</version>
<inherited>false</inherited> <!-- this perticular config is NOT for kids... for parent only -->
<!--some stuff for adults only-->
</executions>
</plugin>
</plugins>
</build>
Ответ 2
Я всегда думал, что дочерняя POM может наследовать определение плагина из родительского раздела pluginManagement и указывать только те версии, которые он хочет запустить из этого плагина, ссылаясь на них с помощью ID и связывая выполнение до фазы. Пока определение родителя находится в pluginManagement (а не непосредственно в плагинах) и не привязано к фазе, на этой фазе будет выполняться только конкретное выполнение (с идентификатором).
Из прочитанного выше и из моей собственной текущей проблемы это выглядит так, как будто это неверно: похоже, что дочерний POM наследует всю конфигурацию плагина, включая все исполнения. С точки зрения исполнения, единственное, что может сделать ребенок, это переопределить определенные значения - он не может выбрать, какие запуска выполнить, а какие нет.
Это ошибка? Какое использование возможности привязывать каждое исполнение к фазе (или нет), если все казни будут выполняться? Я только видел его с maven-dependency-plugin: unpack (привязанный к фазе пакета), но с другими плагинами мне просто повезло...
Блин.
Ответ 3
В родительском pom вы должны настроить выполнение с объявленным <goals>
, но не объявлять <phase>
. Затем в дочернем помпе вы объявите:
<plugin>
<artifactId>some-plugin</artifactId>
<executions>
<execution>
<id>execution-id</id>
<phase>partcular-phase</phase>
</execution>
</executions>
</plugin>
Плагин не будет выполнен, пока вы не определите фазу в дочернем помпе. Таким образом, вам нужно будет явно привязывать выполнение к этапам в каждом дочернем pom (или в середине иерархии), но
вам не нужно будет скопировать конфигурацию этих исполнений.
Обратите внимание, что у множества плагинов есть Фаза по умолчанию, например. Плагин Enforcer привязан к validate
по умолчанию. Даже если вы не привязываете плагин к фазе явно, он все равно будет связан, и, таким образом, будет выполнен плагин. Чтобы преодолеть это, используйте несуществующий этап в своем родителе:
<execution>
<id>execution-id</id>
<goals><goal>some-goal</goal></goals>
<phase>none</phase>
</execution>
Ответ 4
Вы должны назначить идентификатор для выполнения, поэтому maven знает, какие из них переписывают друг друга и которые независимы.