Перейти к основному содержимому

Руководство по классификаторам артефактов Maven

· 7 мин. чтения

1. Обзор

В этом руководстве мы рассмотрим роль классификатора артефактов Maven. После этого мы рассмотрим различные сценарии, в которых они могут быть полезны. Прежде чем закончить, мы также кратко обсудим тип артефакта Maven.

2. Что такое классификатор артефактов Maven?

Классификатор артефактов Maven — это необязательная и произвольная строка , которая добавляется к имени сгенерированного артефакта сразу после номера его версии. Он различает артефакты, созданные из одного и того же POM, но различающиеся по содержимому.

Рассмотрим определение артефакта:

<groupId>com.foreach</groupId>
<artifactId>maven-classifier-example-provider</artifactId>
<version>0.0.1-SNAPSHOT</version>

Для этого плагин Maven jar генерирует maven-classifier-example-provider-0.0.1-SNAPSHOT.jar .

2.1. Создание артефактов с помощью классификатора ``

Давайте добавим конфигурацию классификатора в плагин jar:

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
<executions>
<execution>
<id>Arbitrary</id>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>arbitrary</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

В результате создается maven-classifier-example-provider-0.0.1-SNAPSHOT-arbitrary.jar вместе с maven-classifier-example-provider-0.0.1-SNAPSHOT.jar .

2.2. Использование артефактов с помощью классификатора

Теперь мы можем создать артефакт с настраиваемым суффиксом, используя классификатор. Давайте посмотрим, как мы можем использовать классификатор, чтобы потреблять то же самое.

Чтобы использовать артефакт по умолчанию, нам не нужно делать ничего особенного:

<dependency>
<groupId>com.foreach</groupId>
<artifactId>maven-classifier-example-provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>

Но чтобы использовать артефакт с пользовательским суффиксом «произвольный», нам нужно использовать элемент классификатора в элементе зависимости :

<dependency>
<groupId>com.foreach</groupId>
<artifactId>maven-classifier-example-provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<classifier>arbitrary</classifier>
</dependency>

После всего этого возникает хороший вопрос: зачем нам использовать классификатор? Итак, давайте рассмотрим некоторые практические случаи использования, в которых классификатор был бы полезен.

3. Использование классификатора источников

Мы могли заметить, что каждый артефакт Maven часто сопровождается артефактом « -sources.jar» . Он содержит исходный код, т . е. файлы .java для основного артефакта. Это полезно для целей отладки.

3.1. Генерация артефакта источников

Во-первых, давайте создадим jar- файл с исходным кодом для модуля maven-classifier-example-provider . Для этого мы будем использовать maven-source-plugin :

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<phase>verify</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>

Теперь запустим:

mvn clean install

В результате генерируется артефакт maven-classifier-example-provider-0.0.1-SNAPSHOT-sources.jar .

3.2. Поглощение источников артефакта

Теперь, чтобы использовать артефакт источников, есть несколько способов . Давайте взглянем на один из них. Мы можем получить исходный файл jar для выборочных зависимостей, используя элемент классификатора в определении зависимости:

<dependency>
<groupId>com.foreach</groupId>
<artifactId>maven-classifier-example-producer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<classifier>sources</classifier>
</dependency>

Теперь запустим:

mvn clean install

В результате извлекаются исходные файлы jar для этой конкретной зависимости. Как правило, мы этого не делаем, так как это излишне загрязняет POM. Следовательно, мы обычно предпочитаем использовать возможности IDE для подключения исходных файлов jar по запросу. Кроме того, мы также можем выборочно получить их с помощью команды mvn CLI:

mvn dependency:sources -DincludeArtifactIds=maven-classifier-example-provider

Короче говоря, ключевой вывод здесь заключается в том, что на jar-файл источников ссылаются с помощью классификатора источников .

4. Использование классификатора Javadoc

В том же духе, что и в случае использования jar с исходным кодом, у нас есть Javadoc. Он содержит документацию для основного артефакта jar.

4.1. Создание артефакта Javadoc

Давайте используем maven-javadoc-plugin для создания артефакта Javadoc:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.3.2</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>

Определив плагин, запустим:

mvn clean install

В результате создается артефакт maven-classifier-example-provider-0.0.1-SNAPSHOT-javadoc.jar .

4.2. Использование артефакта Javadoc

Давайте теперь загрузим сгенерированный Javadoc с точки зрения потребителя через mvn :

mvn dependency:resolve -Dclassifier=javadoc -DincludeArtifactIds=maven-classifier-example-provider

Мы можем заметить параметр -Dclassifier=javadoc , который определяет классификатор как javadoc .

5. Использование классификатора тестов

Теперь давайте рассмотрим другой вариант использования классификатора. Могут быть разные причины, по которым мы можем захотеть получить тестовую банку модуля. Во-первых, могут быть определенные тестовые заглушки, которые мы могли бы захотеть использовать повторно. Давайте посмотрим, как мы можем получить тесты в jar независимо от основного артефакта jar с помощью классификатора.

5.1. Создание тестовой банки

Во-первых, давайте сгенерируем тестовую банку для модуля maven-classifier-example-provider . Для этого мы будем использовать плагин Maven jar, указав цель test-jar :

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
<executions>
<execution>
<id>Test Jar</id>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>

Теперь запустим:

mvn clean install

В результате создается и устанавливается jar тестов maven-classifier-example-provider-0.0.1-SNAPSHOT-tests.jar .

5.2. Использование Jar тестов

А теперь давайте добавим зависимость jar тестов в наш потребительский модуль maven-classifier-example-consumer . Мы делаем это с помощью классификатора тестов :

<dependency>
<groupId>com.foreach</groupId>
<artifactId>maven-classifier-example-provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<classifier>tests</classifier>
</dependency>

При этом мы должны иметь доступ к классам, доступным в тестовых пакетах maven-classifier-example-provider .

6. Использование классификаторов для поддержки нескольких версий Java

Ранее мы использовали произвольный классификатор для создания второго jar-файла для нашего модуля maven-classifier-example-provider . Давайте теперь применим это к более практическому применению.

Теперь Java выпускает более новую версию с гораздо более быстрой частотой — 6 месяцев. Следовательно, требуется, чтобы разработчики модулей могли поддерживать несколько версий Java. Создание нескольких jar-файлов для наших модулей, скомпилированных с разными версиями Java, может показаться сложной задачей. Вот тут-то и приходит на помощь классификатор Maven. Мы можем создать несколько jar-файлов, скомпилированных с разными версиями Java, используя один POM.

6.1. Компиляция с несколькими версиями Java

Во-первых, мы настроим подключаемый модуль компилятора Maven для создания скомпилированных файлов классов с использованием как JDK 8, так и JDK 11:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.0</version>
<executions>
<execution>
<id>JDK 8</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<source>8</source>
<target>8</target>
<fork>true</fork>
</configuration>
</execution>
<execution>
<id>JDK 11</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<outputDirectory>${project.build.outputDirectory}_jdk11</outputDirectory>
<executable>${jdk.11.executable.path}</executable>
<source>8</source>
<target>11</target>
<fork>true</fork>
</configuration>
</execution>
</executions>
</plugin>

Мы настраиваем два исполнительных блока, один для Java 8, а другой для Java 11.

После этого мы настроили outputDirectory так , чтобы он отличался для Java 11. С другой стороны, при компиляции Java 8 будет использоваться outputDirectory по умолчанию .

Далее идет конфигурация исходной и целевой версии Java. Исходный код написан с использованием Java 8, поэтому мы сохраняем исходную версию как 8 и модифицируем целевую версию для исполнительного блока Java 11 как 11.

Мы также явно указали путь к исполняемому файлу компилятора Java 11 javac. Для Java 8 Maven будет использовать javac по умолчанию , настроенный в системе, который в данном случае является javac Java 8 :

mvn clean compile

В результате внутри целевой папки будут сгенерированы две папки — classs и class_jdk11 .

6.2. Создание артефактов JAR для нескольких версий Java

Во-вторых, мы можем приступить к упаковке модуля в два отдельных jar-файла с помощью плагина Maven jar:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
<executions>
<execution>
<id>default-package-jdk11</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classesDirectory>${project.build.outputDirectory}_jdk11</classesDirectory>
<classifier>jdk11</classifier>
</configuration>
</execution>
</executions>
</plugin>

Мы можем заметить, что классификатор установлен на jdk11 .

Теперь запустим:

mvn clean install

В результате создаются два jar-файла — maven-classifier-example-provider-0.0.1-SNAPSHOT-jdk11.jar и maven-classifier-example-provider-0.0.1-SNAPSHOT.jar. Первый был скомпилирован с помощью компилятора Java 11, а второй — с помощью компилятора Java 8.

6.3. Использование артефакта Jar конкретной версии Java

И, наконец, потребители нашего модуля могут выбрать, какой jar-артефакт им подходит, в зависимости от используемой версии Java. Давайте посмотрим, как мы можем использовать эти банки с точки зрения потребителя.

Если мы работаем над проектом Java 8, нам не нужно делать ничего особенного. Мы просто добавим ванильную зависимость:

<dependency>
<groupId>com.foreach</groupId>
<artifactId>maven-classifier-example-provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>

Однако, если мы работаем над проектом Java 11, мы должны явно запросить jar, скомпилированный с помощью Java 11, через классификатор:

<dependency>
<groupId>com.foreach</groupId>
<artifactId>maven-classifier-example-provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<classifier>jdk11</classifier>
</dependency>

7. Классификатор артефактов и тип артефакта

Прежде чем мы завершим эту статью, давайте кратко рассмотрим тип артефакта. Хотя тип артефакта и классификатор тесно связаны, они не взаимозаменяемы. Тип артефакта определяет формат упаковки артефакта, например POM или jar. В большинстве случаев это также переводится в расширение файла. Он также может иметь соответствующий классификатор.

Другими словами, тип артефакта имеет дело с упаковкой артефакта и может использовать классификатор для изменения имени сгенерированного артефакта.

Два варианта использования, которые мы видели ранее с Java Sources и Javadoc, являются примерами типов артефактов, которые используют источники и javadoc в качестве классификаторов.

8. Заключение

В этой статье мы увидели, как классификаторы позволяют создавать несколько артефактов из одного файла POM. Используя классификатор, потребители могут выбирать из различных артефактов конкретного модуля по мере необходимости.

Как всегда, образцы кода доступны на GitHub .