1. Введение
Maven предлагает большое разнообразие плагинов, которые помогут нам в сборке нашего проекта. Однако мы можем найти случаи, когда этих плагинов недостаточно, и нам приходится разрабатывать свои собственные.
К счастью, Maven предоставляет несколько полезных инструментов, которые помогут нам в этом процессе.
В этом уроке мы будем достаточно практичными и покажем шаг за шагом, как создать плагин Maven с нуля.
Мы также покажем, как использовать его в наших проектах и как создавать для него документацию.
2. Создание плагина
В рамках этого руководства мы разработаем плагин counter-maven-plugin
, который будет подсчитывать количество зависимостей, содержащихся в проекте. Очень важно следовать соглашению об именах плагинов , которое рекомендует Maven, когда мы выбираем имя для нашего плагина.
Теперь, когда мы знаем, что будем разрабатывать, нам нужно создать проект Maven. В pom.xml
мы определим groupId
, ArtiftId
и версию
нашего плагина:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.foreach</groupId>
<artifactId>counter-maven-plugin</artifactId>
<packaging>maven-plugin</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>counter-maven-plugin Maven Mojo</name>
<url>http://maven.apache.org</url>
<properties>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
</properties>
</project>
Обратите внимание, что мы установили пакет maven-plugin
.
В этом случае мы создали проект вручную, но мы также можем сделать это с помощью maven-archetype-mojo
:
mvn archetype:generate
-DgroupId=com.foreach
-DartifactId=counter-maven-plugin
-Dversion=0.0.1-SNAPSHOT
-DarchetypeGroupId=org.apache.maven.archetypes
-DarchetypeArtifactId=maven-archetype-mojo
При этом мы должны обновить версии зависимостей по умолчанию, чтобы использовать самые последние.
3. Создание моджо
Теперь пришло время создать наше первое моджо. Mojo — это класс Java, представляющий цель, которую будет выполнять наш плагин . Плагин содержит один или несколько моджо.
Наш моджо будет отвечать за подсчет количества зависимостей проекта.
3.1. Добавление зависимостей
Перед созданием моджо нам нужно добавить некоторые зависимости в наш pom.xml
:
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>3.6.3</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>3.6.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-project</artifactId>
<version>2.2.1</version>
</dependency>
</dependencies>
Зависимость maven-plugin-api
является обязательной и содержит необходимые классы и интерфейсы для создания нашего mojo . Зависимость maven-plugin-annotations
пригодится для использования аннотаций в наших классах. Зависимость maven-project
позволяет нам получить доступ к информации о проекте, в который мы включаем плагин.
3.2. Создание класса Mojo
Теперь мы готовы создать наше моджо!
Mojo должен реализовать интерфейс Mojo
. В нашем случае мы будем расширяться от AbstractMojo
, поэтому нам нужно будет только реализовать метод execute
:
@Mojo(name = "dependency-counter", defaultPhase = LifecyclePhase.COMPILE)
public class DependencyCounterMojo extends AbstractMojo {
// ...
}
Как мы видим, имя цели — это счетчик зависимостей .
С другой стороны, мы привязали его к фазе компиляции
по умолчанию, поэтому нам не обязательно указывать фазу при использовании этой цели.
Чтобы иметь доступ к информации о проекте, мы должны добавить MavenProject
в качестве параметра:
@Parameter(defaultValue = "${project}", required = true, readonly = true)
MavenProject project;
Этот объект будет внедрен Maven при создании контекста.
На данный момент мы можем реализовать метод execute и подсчитать количество зависимостей проекта:
public void execute() throws MojoExecutionException, MojoFailureException {
List<Dependency> dependencies = project.getDependencies();
long numDependencies = dependencies.stream().count();
getLog().info("Number of dependencies: " + numDependencies);
}
Метод getLog()
обеспечивает доступ к журналу Maven. AbstractMojo
уже управляет своим жизненным циклом .
3.3. Добавление параметров
Параметр, который мы добавили ранее, доступен только для чтения и не может быть настроен пользователем. Кроме того, он введен Maven, так что мы можем сказать, что он особенный.
В этом разделе мы собираемся добавить параметр, в котором пользователи могут указать объем зависимостей, которые мы хотим подсчитать.
Следовательно, давайте создадим параметр области действия
в нашем моджо:
@Parameter(property = "scope")
String scope;
Мы установили только атрибут свойства
. Это позволяет нам установить это свойство через командную строку или свойство pom .
Для остальных атрибутов нас устраивают значения по умолчанию.
Теперь мы изменим наш метод execute
, чтобы использовать этот параметр и фильтровать зависимости при подсчете:
public void execute() throws MojoExecutionException, MojoFailureException {
List<Dependency> dependencies = project.getDependencies();
long numDependencies = dependencies.stream()
.filter(d -> (scope == null || scope.isEmpty()) || scope.equals(d.getScope()))
.count();
getLog().info("Number of dependencies: " + numDependencies);
}
Более продвинутые типы параметров объясняются в официальной документации .
4. Тестирование плагина
Мы закончили разработку плагина. Давайте проверим, работает ли он!
Прежде всего, мы должны установить плагин в наш локальный репозиторий:
mvn clean install
В следующих разделах мы сначала увидим, как запустить наш плагин из командной строки. Затем мы также расскажем, как использовать его в проекте Maven.
4.1. Выполнение нашего плагина
Мы можем запустить цель плагина в командной строке, указав его полное имя:
mvn groupId:artifactId:version:goal
В нашем случае это выглядит так:
mvn com.foreach:counter-maven-plugin:0.0.1-SNAPSHOT:dependency-counter
Однако, если мы следовали соглашению об именах плагинов, упомянутому в начале этого руководства, Maven разрешит префикс нашего плагина , и мы сможем сократить команду:
mvn counter:dependency-counter
Обратите внимание, что эта команда использует последнюю версию плагина. Кроме того, имейте в виду, что мы должны добавить наш groupId
в pluginGroups
нашего settings.xml,
чтобы Maven также выполнял поиск в этой группе:
<pluginGroups>
<pluginGroup>com.foreach</pluginGroup>
</pluginGroups>
Если мы проверим вывод команды, то увидим, что плагин подсчитал количество зависимостей в pom.xml
нашего плагина:
[INFO] Scanning for projects...
[INFO]
[INFO] -----------------< com.foreach:counter-maven-plugin >------------------
[INFO] Building counter-maven-plugin Maven Mojo 0.0.1-SNAPSHOT
[INFO] ----------------------------[ maven-plugin ]----------------------------
[INFO]
[INFO] --- counter-maven-plugin:0.0.1-SNAPSHOT:dependency-counter (default-cli) @ counter-maven-plugin ---
[INFO] Number of dependencies: 3
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.529 s
[INFO] Finished at: 2019-11-30T20:43:41+01:00
[INFO] ------------------------------------------------------------------------
Мы также можем установить параметр области
через свойства командной строки:
mvn counter:dependency-counter -Dscope=test
Обратите внимание, что имя области
— это то, что мы определили в атрибуте свойства
нашего параметра в файле mojo.
4.2. Использование нашего плагина в проекте
Давайте теперь протестируем наш плагин, используя его в проекте!
Мы собираемся создать очень простой проект Maven с некоторыми зависимостями, которые будет учитывать наш плагин:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.foreach</groupId>
<artifactId>example</artifactId>
<packaging>pom</packaging>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Последнее, что нужно сделать, это добавить наш плагин в файл build. Мы должны явно указать, что мы хотим запустить цель счетчика зависимостей :
<build>
<plugins>
<plugin>
<groupId>com.foreach</groupId>
<artifactId>counter-maven-plugin</artifactId>
<version>0.0.1-SNAPSHOT</version>
<executions>
<execution>
<goals>
<goal>dependency-counter</goal>
</goals>
</execution>
</executions>
<configuration>
<scope>test</scope>
</configuration>
</plugin>
</plugins>
</build>
Обратите внимание, что мы указали параметр области действия
в узле конфигурации .
Кроме того, мы не указали какую-либо фазу, потому что наше моджо по умолчанию привязано к фазе компиляции .
Теперь нам просто нужно запустить фазу компиляции
, чтобы выполнить наш плагин:
mvn clean compile
И наш плагин выведет количество тестовых
зависимостей:
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------< com.foreach:example >------------------------
[INFO] Building example 0.0.1-SNAPSHOT
[INFO] --------------------------------[ pom ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ example ---
[INFO]
[INFO] --- counter-maven-plugin:0.0.1-SNAPSHOT:dependency-counter (default) @ example ---
[INFO] Number of dependencies: 1
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.627 s
[INFO] Finished at: 2019-11-25T18:57:22+01:00
[INFO] ------------------------------------------------------------------------
В этом руководстве мы не рассказываем, как писать модульные или интеграционные тесты для нашего плагина, но Maven предоставляет некоторые механизмы для этого.
5. Добавление документации
Когда мы создаем подключаемый модуль Maven, важно создать документацию, чтобы другим людям было легко его использовать .
Мы кратко расскажем, как создать эту документацию с помощью maven-plugin-plugin
.
maven-plugin-plugin
уже включен в проект, но мы собираемся обновить его, чтобы использовать последнюю версию.
Кроме того, мы сделаем то же самое для maven-site-plugin
:
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.6.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.8.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
Затем мы должны убедиться, что добавили javadoc
в наш Mojo
, а также добавить некоторые метаданные в pom.xml
плагина:
<organization>
<name>ForEach</name>
<url>https://www.foreach.com/</url>
</organization>
После этого нам нужно добавить раздел отчетов в наш pom.xml
:
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<reportSets>
<reportSet>
<reports>
<report>report</report>
</reports>
</reportSet>
</reportSets>
</plugin>
</plugins>
</reporting>
Наконец, мы создадим документацию с помощью команды maven site:
mvn site
Внутри целевой папки мы можем найти каталог сайта
со всеми сгенерированными файлами HTML. plugin - info.html
содержит документацию плагина:
Дополнительные параметры для добавления в нашу документацию можно найти в руководстве по документации плагинов Maven .
6. Заключение
В этом руководстве мы показали, как создать плагин Maven. Сначала мы реализовали простой плагин, который помог нам увидеть типичную структуру проекта плагина Maven. Затем мы рассмотрели некоторые инструменты, которые Maven предоставляет для помощи в разработке плагинов.
Мы упростили его, чтобы сделать его более понятным, но в то же время мы предоставили несколько полезных ссылок с необходимой информацией о том, как создать более мощный плагин.
Как всегда, полный исходный код примеров доступен на GitHub .