Всем привет!
Сегодня расскажу о нескольких неочевидных особенностях работы Maven.
1) за каждый этап жизненного цикла сборки Maven отвечает какой-то плагин. Один плагин может покрывать несколько этапов. Это не новость. Я надеюсь) Интересно то, что эти плагины не обязательно указывать в pom, вот минимальный рабочий pom, с которым ваш проект скомпилируется - https://maven.apache.org/guides/introduction/introduction-to-the-pom.html#Minimal_POM
Работает принцип convention over configuration.
А вот описание алгоритма определения нужного плагина: https://maven.apache.org/guides/introduction/introduction-to-plugin-prefix-mapping.html
Перескажу его вкратце.
Если вы указали при сборке фазу жизненного цикла, например, maven install, то определяются все необходимые шаги сборки и требуемые плагины как описано вот тут https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html
А далее Maven ищет специальные файлы maven-metadata во всех подключенных к проекту репо, сливает их в один и ищет плагин по атрибуту prefix, который равен указаному вот тут как plugin https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#default-lifecycle-bindings-packaging-ejb-ejb3-jar-par-rar-war
Вот пример базового maven-metadata из Maven Central https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-metadata.xml
Как можно заметить, у большинства плагинов, поисковый префикс является частью artefactId. Это соглашение о наименовании, хотя и не обязательное. Т.е. всегда можно сделать свой maven-metadata-local.xml и привязать нужный плагин к нужной фазе там. Но я бы не рекомендовал так делать, т.к. это завязка на конкретный сборщик, которая хранится отдельно от кода вашего проекта. Также при создании плагина можно назвать его как угодно и указать к какой фазе сборки он привязан, может быть полезно, когда одним словом сложно выразить задачу плагина.
Если вы явно указываете цель для сборки, например, compiler:compile, то выполняется только эта цель, Maven пропускает разбор жизненного цикла сборки, сразу переходит к поиску нужного плагина в maven-metadata, в данном случае по префиксу compiler.
Вопрос - а как Maven определяет версию плагина? Есть еще один maven-metadata файлик с версиями у каждого плагина https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-compiler-plugin/maven-metadata.xml
И как раз здесь лежит подводный камень: когда Maven-у понадобится конкретный плагин - он возьмет последнюю версию из тех, что найдет в подключенных к проекту репозиториях. А брать последнюю версию не всегда хорошо - там могут быть баги, или она просто может криво закачаться, если речь про внутренний прокси репозиторий.
Поэтому рекомендую начинать с минимальным POM, а перед выходом на ПРОМ фиксировать все версии плагинов.
Еще может возникнуть вопрос - а нельзя ли этот фокус провернуть с неофициальными плагинами? Ответ - можно, нужно лишь указать в settings.xml где еще искать maven-metadata.xml:
<pluginGroups>
<pluginGroup>org.codehaus.modello</pluginGroup>
</pluginGroups>
Еще момент - всегда можно добавить в pom конфигурацию плагина и там переопределить фазу сборки, на которой он запустится.
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<executions>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
В примере цель из плагина jacoco-maven-plugin привяза к фазе test.
Выше я описывал, как работает Maven в режиме convention over configuration.
Продолжение следует...
#maven #buildtool #conv_over_conf
Сегодня расскажу о нескольких неочевидных особенностях работы Maven.
1) за каждый этап жизненного цикла сборки Maven отвечает какой-то плагин. Один плагин может покрывать несколько этапов. Это не новость. Я надеюсь) Интересно то, что эти плагины не обязательно указывать в pom, вот минимальный рабочий pom, с которым ваш проект скомпилируется - https://maven.apache.org/guides/introduction/introduction-to-the-pom.html#Minimal_POM
Работает принцип convention over configuration.
А вот описание алгоритма определения нужного плагина: https://maven.apache.org/guides/introduction/introduction-to-plugin-prefix-mapping.html
Перескажу его вкратце.
Если вы указали при сборке фазу жизненного цикла, например, maven install, то определяются все необходимые шаги сборки и требуемые плагины как описано вот тут https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html
А далее Maven ищет специальные файлы maven-metadata во всех подключенных к проекту репо, сливает их в один и ищет плагин по атрибуту prefix, который равен указаному вот тут как plugin https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#default-lifecycle-bindings-packaging-ejb-ejb3-jar-par-rar-war
Вот пример базового maven-metadata из Maven Central https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-metadata.xml
Как можно заметить, у большинства плагинов, поисковый префикс является частью artefactId. Это соглашение о наименовании, хотя и не обязательное. Т.е. всегда можно сделать свой maven-metadata-local.xml и привязать нужный плагин к нужной фазе там. Но я бы не рекомендовал так делать, т.к. это завязка на конкретный сборщик, которая хранится отдельно от кода вашего проекта. Также при создании плагина можно назвать его как угодно и указать к какой фазе сборки он привязан, может быть полезно, когда одним словом сложно выразить задачу плагина.
Если вы явно указываете цель для сборки, например, compiler:compile, то выполняется только эта цель, Maven пропускает разбор жизненного цикла сборки, сразу переходит к поиску нужного плагина в maven-metadata, в данном случае по префиксу compiler.
Вопрос - а как Maven определяет версию плагина? Есть еще один maven-metadata файлик с версиями у каждого плагина https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-compiler-plugin/maven-metadata.xml
И как раз здесь лежит подводный камень: когда Maven-у понадобится конкретный плагин - он возьмет последнюю версию из тех, что найдет в подключенных к проекту репозиториях. А брать последнюю версию не всегда хорошо - там могут быть баги, или она просто может криво закачаться, если речь про внутренний прокси репозиторий.
Поэтому рекомендую начинать с минимальным POM, а перед выходом на ПРОМ фиксировать все версии плагинов.
Еще может возникнуть вопрос - а нельзя ли этот фокус провернуть с неофициальными плагинами? Ответ - можно, нужно лишь указать в settings.xml где еще искать maven-metadata.xml:
<pluginGroups>
<pluginGroup>org.codehaus.modello</pluginGroup>
</pluginGroups>
Еще момент - всегда можно добавить в pom конфигурацию плагина и там переопределить фазу сборки, на которой он запустится.
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<executions>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
В примере цель из плагина jacoco-maven-plugin привяза к фазе test.
Выше я описывал, как работает Maven в режиме convention over configuration.
Продолжение следует...
#maven #buildtool #conv_over_conf
maven.apache.org
Introduction to the POM – Maven
👍2🔥1