Учебник по Apache Maven

1. Вступление

Создание программного проекта обычно состоит из таких задач, как загрузка зависимостей, размещение дополнительных jar-файлов в пути к классам, компиляция исходного кода в двоичный код, выполнение тестов, упаковка скомпилированного кода в развертываемые артефакты, такие как файлы JAR, WAR и ZIP, и развертывание этих артефактов. на сервер приложений или в хранилище.

Apache Maven автоматизирует эти задачи, сводя к минимуму риск того, что люди совершат ошибки при сборке программного обеспечения вручную и отделит работу по компиляции и упаковке нашего кода от процесса конструирования кода.

В этом руководстве мы собираемся исследовать этот мощный инструмент для описания, создания и управления проектами программного обеспечения Java с использованием центральной части информации - Project Object Model (POM) - которая написана на XML.

2. Зачем использовать Maven?

Ключевые особенности Maven:

  • простая настройка проекта в соответствии с лучшими практиками: Maven пытается

избегайте как можно большей конфигурации, предоставляя шаблоны проектов (названный archetypes ) управление зависимостями: ** включает автоматическое обновление, загрузку

и проверка совместимости, а также сообщение о зависимости замыкания (известные также как транзитивные зависимости) изоляция между зависимостями проекта и плагинами: ** с Maven,

зависимости проекта извлекаются из репозиториев dependency в то время как зависимости любого плагина извлекаются из plugin репозитории, приводящие к уменьшению конфликтов, когда плагины начинают скачать дополнительные зависимости центральная система репозитория: ** зависимости проекта могут быть загружены из

локальная файловая система или общедоступные репозитории, такие как Maven Central

  • Чтобы узнать, как установить Maven в вашей системе, проверьте ссылку:/install-maven-on-windows-linux-mac[это руководство по Baeldung]. **

3. Объектная модель проекта

Конфигурирование проекта Maven выполняется через Project Object Model (POM) , представленную файлом pom.xml . POM описывает проект, управляет зависимостями и настраивает плагины для сборки программного обеспечения.

POM также определяет отношения между модулями многомодульных проектов. Давайте посмотрим на базовую структуру типичного файла POM :

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.baeldung</groupId>
    <artifactId>org.baeldung</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>org.baeldung</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
           //...
            </plugin>
        </plugins>
    </build>
</project>

Давайте внимательнее посмотрим на эти конструкции.

3.1. Идентификаторы проекта

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

  • groupId - уникальное базовое имя компании или группы, которая создала

проект ** artifactId - уникальное имя проекта

  • version - версия проекта

  • packaging - способ упаковки (например, WAR / JAR / ZIP )

Первые три из них ( groupId: artifactId: version ) объединяются, чтобы сформировать уникальный идентификатор, и представляют собой механизм, с помощью которого вы указываете, какие версии внешних библиотек (например, JAR) будут использовать ваш проект.

3.2. зависимости

Эти внешние библиотеки, которые использует проект, называются зависимостями.

Функция управления зависимостями в Maven обеспечивает автоматическую загрузку этих библиотек из центрального хранилища, поэтому вам не нужно хранить их локально.

Это ключевая особенность Maven и обеспечивает следующие преимущества:

  • ** использует меньше памяти за счет значительного сокращения количества скачиваний

отключить удаленные репозитории делает проверку проекта быстрее

  • ** обеспечивает эффективную платформу для обмена двоичными артефактами внутри

вашей организации и за ее пределами без необходимости каждый раз создавать артефакт из источника **

Чтобы объявить зависимость от внешней библиотеки, вам нужно предоставить groupId, artifactId и version библиотеки.

Давайте посмотрим на пример:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>4.3.5.RELEASE</version>
</dependency>

Когда Maven обрабатывает зависимости, он загружает библиотеку Spring Core в ваш локальный репозиторий Maven.

3.3. Хранилища

Репозиторий в Maven используется для хранения артефактов сборки и зависимостей различных типов. Локальный репозиторий по умолчанию находится в папке .m2/repository в домашнем каталоге пользователя.

Если в локальном репозитории имеется артефакт или плагин, Maven использует его. В противном случае он загружается из центрального хранилища и сохраняется в локальном хранилище. Центральный репозиторий по умолчанию - Maven Central .

Некоторые библиотеки, такие как сервер JBoss, недоступны в центральном хранилище, но доступны в альтернативном хранилище. Для этих библиотек необходимо указать URL-адрес альтернативного хранилища в файле pom.xml :

<repositories>
    <repository>
        <id>JBoss repository</id>
        <url>http://repository.jboss.org/nexus/content/groups/public/</url>
    </repository>
</repositories>
  • Обратите внимание, что вы можете использовать несколько репозиториев в своих проектах. **

3.4. Свойства

Пользовательские свойства могут помочь сделать ваш файл pom.xml более удобным для чтения и обслуживания. В классическом случае вы будете использовать пользовательские свойства для определения версий для зависимостей вашего проекта.

  • Свойства Maven являются заполнителями значений и доступны в любом месте pom.xml с помощью нотации $ \ {name} ** , где name - это свойство.

Давайте посмотрим на пример:

<properties>
    <spring.version>4.3.5.RELEASE</spring.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
</dependencies>

Теперь, если вы хотите обновить Spring до более новой версии, вам нужно всего лишь изменить значение внутри тега свойства _ <spring.version> , и все зависимости, использующие это свойство в своих тегах <version> _ , будут обновлены.

Свойства также часто используются для определения переменных пути сборки:

<properties>
    <project.build.folder>${project.build.directory}/tmp/</project.build.folder>
</properties>

<plugin>
   //...
    <outputDirectory>${project.resources.build.folder}</outputDirectory>
   //...
</plugin>

3.5. построить

Раздел build также является очень важным разделом Maven POM. Он предоставляет информацию о Maven goal по умолчанию, каталоге скомпилированного проекта и окончательном имени приложения. Раздел build__ по умолчанию выглядит следующим образом:

<build>
    <defaultGoal>install</defaultGoal>
    <directory>${basedir}/target</directory>
    <finalName>${artifactId}-${version}</finalName>
    <filters>
      <filter>filters/filter1.properties</filter>
    </filters>
   //...
</build>
  • Папка вывода по умолчанию для скомпилированных артефактов называется target , а окончательное имя упакованного артефакта состоит из artifactId и version , но вы можете изменить его в любое время.

3.6. Использование Profiles

Еще одна важная особенность Maven - поддержка profiles. profile - это, по сути, набор значений конфигурации. Используя profiles , вы можете настроить сборку для различных сред, таких как Производство/Тестирование/Разработка:

<profiles>
    <profile>
        <id>production</id>
        <build>
            <plugins>
                <plugin>
               //...
                </plugin>
            </plugins>
        </build>
    </profile>
    <profile>
        <id>development</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <build>
            <plugins>
                <plugin>
               //...
                </plugin>
            </plugins>
        </build>
     </profile>
 </profiles>

Как видно из приведенного выше примера, для профиля по умолчанию установлено значение development . Если вы хотите запустить production profile , вы можете использовать следующую команду Maven:

mvn clean install -Pproduction

4. Жизненные циклы Maven Build

Каждая сборка Maven следует указанному lifecycle . Вы можете выполнить несколько сборок lifecycle goals , в том числе для компиляции кода проекта, создания package, и install файла архива в локальном репозитории зависимостей Maven.

4.1. Lifecycle Phases

В следующем списке показаны наиболее важные фазы Maven lifecycle :

  • validate - проверяет правильность проекта

  • compile - компилирует предоставленный исходный код в двоичные артефакты

  • test - выполняет модульные тесты

  • package - упаковывает скомпилированный код в файл архива

  • integration-test - выполняет дополнительные тесты, которые требуют

упаковка ** verify - проверяет, является ли пакет действительным

  • install - устанавливает файл пакета в локальный репозиторий Maven

  • deploy - развертывает файл пакета на удаленном сервере или в хранилище

4.2. Plugins и Goals

Maven plugin представляет собой набор из одного или нескольких goals . Цели выполняются поэтапно, что помогает определить порядок выполнения goals .

Богатый список плагинов, которые официально поддерживаются Maven, доступен по адресу here . ** Есть также интересная статья о том, как связать:/executetable-jar-with-maven[создать исполняемый файл JAR на Baeldung]с использованием различных плагинов.

Чтобы лучше понять, на каких этапах по умолчанию выполняются goals , посмотрите http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Built-in Lifecycle Bindings[default. Maven lifecycle bindings].

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

mvn <phase>

Например, mvn clean install удалит ранее созданные файлы jar/war/zip и скомпилированные классы ( clean) и выполнит все фазы, необходимые для установки нового архива ( install)

  • Обратите внимание, что goals , предоставляемые plugins , могут быть связаны с различными фазами lifecycle . **

5. Ваш первый проект Maven

В этом разделе мы будем использовать функциональность командной строки Maven для создания проекта Java.

5.1. Генерация простого Java-проекта

Чтобы построить простой Java-проект, давайте запустим следующую команду:

mvn archetype:generate
  -DgroupId=org.baeldung
  -DartifactId=org.baeldung.java
  -DarchetypeArtifactId=maven-archetype-quickstart
  -DinteractiveMode=false

GroupId - это параметр, указывающий группу или отдельное лицо, создавшее проект, которое часто является обратным доменным именем компании. ArtifactId - это имя базового пакета, используемое в проекте, и мы используем стандартный archetype .

Поскольку мы не указали версию и тип упаковки, для них будут заданы значения по умолчанию - для версии будет задано 1.0-SNAPSHOT, и для упаковки будет задано jar .

  • Если вы не знаете, какие параметры предоставить, вы всегда можете указать _interactiveMode = true_ , чтобы Maven запрашивал все необходимые параметры. **

После завершения команды у нас есть проект Java, содержащий класс App.java , который является простой программой «Hello World», в папке src/main/java .

У нас также есть пример тестового класса в src/test/java. Pom.xml этого проекта будет выглядеть примерно так:

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.baeldung</groupId>
    <artifactId>org.baeldung.java</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>org.baeldung.java</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.1.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

Как видите, зависимость junit предоставляется по умолчанию.

5.2. Компиляция и упаковка проекта

Следующим шагом является компиляция проекта:

mvn compile

Maven будет проходить все этапы lifecycle , необходимые на этапе compile для создания исходных текстов проекта. Если вы хотите запустить только фазу test , вы можете использовать:

mvn test

Теперь давайте вызовем фазу package _, , которая создаст файл jar_ скомпилированного архива:

mvn package

5.3. Выполнение заявки

Наконец, мы собираемся выполнить наш Java-проект с помощью exec-maven-plugin . Давайте настроим необходимые плагины в pom.xml :

<build>
    <sourceDirectory>src</sourceDirectory>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.6.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>1.5.0</version>
            <configuration>
                <mainClass>org.baeldung.java.App</mainClass>
            </configuration>
        </plugin>
    </plugins>
</build>

Первый плагин maven-compiler-plugin отвечает за компиляцию исходного кода с использованием Java версия 1.8. Https://search.maven.org/classic/#search%7Cga%7C1%7Ca%3A%22exec-maven-plugin%22[ exec-maven-plugin ]ищет mainClass в нашем проекте.

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

mvn exec:java

6. Мультимодульные проекты

Механизм в Maven, который обрабатывает многомодульные проекты (также называемые aggregator projects), называется Reactor .

Reactor собирает все доступные модули для сборки, затем сортирует проекты в правильном порядке сборки и, наконец, строит их один за другим.

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

6.1. Создать родительский проект

Прежде всего, нам нужно создать родительский проект. Чтобы создать новый проект с именем parent-project, мы используем следующую команду:

mvn archetype:generate -DgroupId=org.baeldung -DartifactId=parent-project

Затем мы обновляем тип упаковки внутри файла pom.xml , чтобы указать, что это модуль parent :

<packaging>pom</packaging>

6.2. Создать проекты субмодулей

На следующем шаге мы создаем проекты субмодулей из каталога parent-project :

cd parent-project
mvn archetype:generate -DgroupId=org.baeldung  -DartifactId=core
mvn archetype:generate -DgroupId=org.baeldung  -DartifactId=service
mvn archetype:generate -DgroupId=org.baeldung  -DartifactId=webapp

Чтобы проверить, правильно ли мы создали подмодули, мы смотрим в файле parent-project pom.xml , где мы должны увидеть три модуля:

<modules>
    <module>core</module>
    <module>service</module>
    <module>webapp</module>
</modules>

Более того, родительский раздел будет добавлен в pom.xml каждого подмодуля:

<parent>
    <groupId>org.baeldung</groupId>
    <artifactId>parent-project</artifactId>
    <version>1.0-SNAPSHOT</version>
</parent>

6.3. Включить управление зависимостями в родительском проекте

Управление зависимостями - это механизм для централизации информации о зависимостях для родительского проекта muti-module и его дочерних элементов.

Если у вас есть набор проектов или модулей, которые наследуют общего родителя, вы можете поместить всю необходимую информацию о зависимостях в общий файл pom.xml . Это упростит ссылки на артефакты в дочернем __POM __s.

Давайте посмотрим на пример родительского pom.xml :

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.3.5.RELEASE</version>
        </dependency>
       //...
    </dependencies>
</dependencyManagement>

Объявляя версию spring-core в родительском объекте, все подмодули, зависящие от spring-core , могут объявить зависимость, используя только groupId и artifactId , и версия будет наследоваться

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
    </dependency>
   //...
</dependencies>

Более того, вы можете предоставить исключения для управления зависимостями в родительском pom.xml , чтобы определенные библиотеки не наследовались дочерними модулями:

<exclusions>
    <exclusion>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
    </exclusion>
</exclusions>

Наконец, если дочернему модулю нужно использовать другую версию управляемой зависимости, вы можете переопределить управляемую версию в файле pom.xml дочернего элемента:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>4.2.1.RELEASE</version>
</dependency>
  • Обратите внимание, что хотя дочерние модули наследуют от своего родительского проекта, родительский проект не обязательно имеет какие-либо модули, которые он объединяет. С другой стороны, родительский проект может также объединять проекты, которые не наследуются от него. **

Для получения дополнительной информации о наследовании и агрегации please обратитесь к этой документации .

6.4. Обновление субмодулей и построение проекта

Мы можем изменить тип packaging каждого подмодуля. Например, давайте изменим packaging модуля webapp на WAR , обновив файл pom.xml :

<packaging>war</packaging>

Теперь мы можем протестировать сборку нашего проекта с помощью команды mvn clean install . Выходные данные журналов Maven должны быть похожи на это:

----[INFO]Scanning for projects...[INFO]Reactor build order:[INFO]  parent-project[INFO]  core[INFO]  service[INFO]  webapp//.............[INFO]-----------------------------------------[INFO]Reactor Summary:[INFO]-----------------------------------------[INFO]parent-project .................. SUCCESS[2.041s][INFO]core ............................ SUCCESS[4.802s][INFO]service ......................... SUCCESS[3.065s][INFO]webapp .......................... SUCCESS[6.125s][INFO]-----------------------------------------
----

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

В этой статье мы обсудили некоторые из наиболее популярных функций инструмента сборки Apache Maven.

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