Apache Maven

Эта статья находится на начальном уровне проработки, в одной из её версий выборочно используется текст из источника, распространяемого под свободной лицензией
Материал из энциклопедии Руниверсалис
Apache Maven
Логотип программы Apache Maven
Тип Автоматизация сборки и система управления пакетами
Страна  США
Разработчик Apache Software Foundation
Написана на Java
Операционная система кроссплатформенность
Первый выпуск 1 февраля 2008
Аппаратная платформа JVM
Последняя версия 3.9.6 (1 декабря 2023)
Читаемые форматы файлов Maven metadata
Создаваемые форматы файлов Maven metadata
Лицензия Apache License 2.0
Ссылки
Сайт maven.apache.org
gitbox.apache.org/repos/asf/maven.git

Apache Maven — фреймворк для автоматизации сборки проектов на основе описания их структуры в файлах на языке POM (англ. Project Object Model), являющемся подмножеством XML[1]. Проект Maven издаётся сообществом Apache Software Foundation, где формально является частью Jakarta Project.

Название системы является словом из языка идиш, смысл которого можно примерно выразить как «собиратель знания»[2].

Maven обеспечивает декларативную, а не императивную (в отличие от средства автоматизации сборки Apache Ant) сборку проекта. В файлах описания проекта содержится его спецификация, а не отдельные команды выполнения. Все задачи по обработке файлов, описанные в спецификации, Maven выполняет посредством их обработки последовательностью встроенных и внешних плагинов.

Maven используется для построения и управления проектами, написанными на JavaC#RubyScala, и других языках[3].

Среди примечательных альтернатив — система автоматической сборки Gradle, построенная на принципах Apache Ant и Maven, но использующая специализированный DSL на Groovy вместо POM-конфигурации.

История разработки

Maven был создан канадцем Ясоном ван Зилом (Jason van Zyl) и организованной им фирмой Sonatype. Он начался как подпроект Apache Turbine в 2002 году, в 2003 году Maven был квалифицирован как Apache-проект верхнего уровня, тогда же появилась его первая версия — Maven 1.x, опубликованная 13 июля 2004 года как версия 1.0. Это происходило, однако, так быстро, что некоторые частности оказались непродуманными, например, слишком много конфигурации, проблемы с производительностью.

Поэтому концепция была доработана и с 2005 года началась параллельная разработка Maven 2.x, которая была сдана в версии 2.0 19 октября 2005 года.[4]

Maven 1.x не разрабатывается дальше и ограничивается поддержкой пользователей и устранением ошибок.[5]

Разработка Maven 3.0 началась в 2008 году. После восьми альфа-релизов, первая бета-версия Maven 3.0 была опубликована в октябре 2010 года. Особенное внимание было уделено её обратной совместимости с Maven 2. Для большинства проектов переход от версии Maven 2 к версии Maven 3 не требует никаких изменений[6].

Разработка Maven происходит в следующих подпроектах:

  • Maven 1.x и Maven 2.x — старые версии Maven.
  • Maven 3.x развивает текущую линию продуктов Maven[6].
  • Plugins разрабатывает большинство maven-плагинов.
  • Shared Components изготовляет компоненты программного обеспечения, которые могут использоваться всеми другими подпроектами.
  • Ant Tasks позволяет использовать возможности Ant из Maven.
  • Doxia — фреймворк для генерации контента из форматов Almost Plain Text (APT), Confluence, DocBook, FML (FAQ Markup Language), LaTeX, Rich Text Format (RTF), TWiki, XDoc и XHTML.
  • SCM (Source Code Management) разрабатывает программное обеспечение для подключения Apache к различным системам версионирования как CVS или Subversion.
  • Surefire разрабатывает тест-фреймворк для Maven-а.
  • Wagon готовит абстракцию коммуникационных протоколов как «доступ к файлам», HTTP или FTP.

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

Информация для сборки проекта, поддерживаемого Apache Maven, содержится в XML-файле с названием pom.xml. При запуске Maven проверяет, содержит ли конфигурационный файл все необходимые данные и все ли данные синтаксически правильно записаны.

Пример файла pom.xml:

<project>
  <!-- версия модели для POM-ов Maven 2.x всегда 4.0.0 -->
  <modelVersion>4.0.0</modelVersion>
  
  <!-- координаты проекта, то есть набор значений, который
       позволяет однозначно идентифицировать этот проект -->
  
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1.0</version>

  <!-- зависимости от библиотек -->
  
  <dependencies>
    <dependency>
    
      <!-- координаты необходимой библиотеки -->
      
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      
      <!-- эта библиотека используется только для запуска и компилирования тестов -->
      
      <scope>test</scope>
      
    </dependency>
  </dependencies>
</project>

Минимальная конфигурация включает версию конфигурационного файла, имя проекта, его автора и версию[7]. С помощью pom.xml конфигурируются зависимости от других проектов, индивидуальные фазы процесса построения проекта (build process), список плагинов, реализующих порядок сборки[7].

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

POM-файлы подпроектов могут наследовать конфигурацию от других файлов конфигурации. В то же время все файлы конфигурации обязательно наследуются от «Супер POM» файла[8] по умолчанию. Супер POM обеспечивает конфигурацию по умолчанию, например, стандартная структура каталогов, используемые по умолчанию плагины, привязка к фазам жизненного цикла и прочее.

Основные концепции

Соглашения по конфигурации

Maven поддерживает принцип соглашения по конфигурации, заключающийся в том, что рассматриваемые аспекты нуждаются в конфигурации тогда и только тогда, когда этот аспект не удовлетворяет некоторой спецификации. Как следствие, это позволяет сократить количество требуемой конфигурации без потери гибкости. Одним из следствий применения данного принципа является то, что отсутствует необходимость указывать пути к файлам в явном виде, что упрощает содержимое pom.xml. Однако, почти все стандарты, на которые опирается Maven, могут быть изменены индивидуальной конфигурацией[9][10].

Архетипы

Maven автоматически генерирует представленную структуру для Java-проекта.

Maven использует принцип Maven-архетипов (англ. Archetypes). Архетип — это инструмент шаблонов, каждый из которых определён паттерном или моделью, по аналогии с которой создаются производные.[11]

Стандартная структура каталогов — одна из реализаций принципа архетипов в Maven. Следующая структура показывает важнейшие каталоги для проекта на Java[12]:

  • Корневой каталог проекта: файл pom.xml и все дальнейшие подкаталоги
    • src: все исходные файлы
      • src/main: исходные файлы собственно для продукта
        • src/main/java: исходный текст на Java
        • src/main/resources: другие файлы, которые используются при компиляции или исполнении, например properties-файлы
      • src/test: исходные файлы, необходимые для организации автоматического тестирования
        • src/test/java: JUnit-тест-задания для автоматического тестирования
    • target: все создаваемые в процессе работы Мавена файлы
      • target/classes: компилированные Java-классы

Жизненный цикл

Жизненный цикл maven-проекта — это список поименованных фаз, определяющий порядок действий при его построении. Жизненный цикл Maven содержит три независимых порядка выполнения:[13]

  • clean — жизненный цикл для очистки проекта. Содержит следующие фазы:
    1. pre-clean
    2. clean
    3. post-clean
  • default — основной жизненный цикл, содержащий следующие фазы:
    1. validate — выполняется проверка, является ли структура проекта полной и правильной.
    2. generate-sources
    3. process-sources
    4. generate-resources
    5. process-resources
    6. compile — компилируются исходные тексты.
    7. process-test-sources
    8. process-test-resources
    9. test-compile
    10. test — собранный код тестируется заранее подготовленным набором тестов.
    11. package — упаковка откомпилированных классов и прочих ресурсов. Например, в JAR-файл.
    12. integration-test — программное обеспечение в целом или его крупные модули подвергаются интеграционному тестированию. Проверяется взаимодействие между составными частями программного продукта.
    13. install — установка программного обеспечения в локальный Maven-репозиторий, чтобы сделать его доступным для других проектов текущего пользователя.
    14. deploy — стабильная версия программного обеспечения распространяется на удаленный Maven-репозиторий, чтобы сделать его доступным для других пользователей.
  • site — жизненный цикл генерации проектной документации. Состоит из фаз:
    1. pre-site
    2. site
    3. post-site
    4. site-deploy

Стандартные жизненные циклы могут быть дополнены функционалом с помощью Maven-плагинов. Плагины позволяют вставлять в стандартный цикл новые шаги (например, распределение на сервер приложений) или расширять существующие шаги.

Архитектура

Maven базируется на plugin-архитектуре, которая позволяет применять плагины для различных задач (англ. compile, test, build, deploy, checkstyle, pmd, scp-transfer) для данного проекта, без необходимости их в явном виде инсталлировать. Это возможно за счет того, что информация поступает плагину через стандартный вход, а результаты пишутся в его стандартный выход. Теоретически, это позволяет кому угодно писать плагины для взаимодействия со средствами построения проекта (компиляторы, средства тестирования, и так далее) для любого другого языка. В реальности, поддержка других языков кроме Java сейчас минимальна. Существует плагин для .NET-фреймворка[14], а также плагины для C/C++[15][16].

Количество доступных плагинов в настоящее время очень велико и включает, в том числе, плагины, позволяющие непосредственно из Maven запускать web-приложение для тестирования его в браузере; плагины, позволяющие тестировать или создавать банки данных; плагины, позволяющие генерировать Web Services. Задачей разработчика в такой ситуации является найти и применить наиболее подходящий набор плагинов.

Плагин обеспечивает достижение ряда целей с помощью следующего синтаксиса:

 mvn [имя плагина]:[имя цели]

Например, Java-проект может быть скомпилирован плагином-компилятором[17] путём выполнения команды mvn compiler:compile.

Существуют Maven-плагины для построения, тестирования, контроля исходного текста, запуска web-сервера, генерации Eclipse-проектных файлов и множество других.[18] Плагины перечисляются и конфигурируются в секции <plugins> файла pom.xml. Некоторая базовая группа плагинов включается в каждый проект по умолчанию.

Зависимости

В файле pom.xml задаются зависимости, которые имеет управляемый с помощью Maven проект. Менеджер зависимостей основан на нескольких основных принципах:

  • Репозитории. Maven ищет необходимые файлы в локальных каталогах или в локальном maven-репозитории. Если зависимость не может быть локально разрешена, Maven подключается к указанному maven-репозиторию в сети и копирует в локальный репозиторий. По умолчанию Maven использует Maven Central Repository[19], но разработчик может конфигурировать и другие публичные Maven-репозитории, такие, как Apache, Ibiblio, Codehaus или Java.Net.
  • Транзитивные зависимости. Необходимые библиотеки подгружаются в проект автоматически. При разрешении конфликта версий используется принцип «ближайшей» зависимости, то есть выбирается зависимость, путь к которой через список зависимых проектов является наиболее коротким.
  • Исключение зависимостей. Файл описания проекта предусматривает возможность исключить зависимость в случае обнаружения цикличности или отсутствия необходимости в определённой библиотеке.
  • Поиск зависимостей. Поиск зависимостей (open-source-библиотек и модулей) ведётся по их координатам (groupId, artifactId и version). Эти координаты могут быть определены с помощью специальных поисковых машин, например, Maven search engine[20]. Например, по поисковому признаку «pop3» поисковая машина предоставляет результат с groupId="com.sun.mail" и artifactId="pop3".
  • Менеджеры репозиториев. Репозитории реализуются с помощью менеджеров репозиториев Maven (Maven Repository Manager), таких как Apache Archiva, Nexus (ранее Proximity), Artifactory, Codehaus Maven Proxy или Dead Simple Maven Proxy[21].

Область распространения зависимости позволяет включать зависимости только на определённую стадию построения проекта. Существует 6 возможных областей[22]:

  1. compile. Область по умолчанию. Зависимость доступна во всех путях поиска классов в проекте. Распространяется на зависимые проекты.
  2. provided. Область аналогична compile, за исключением того, что JDK или контейнер сам предоставит зависимость во время выполнения программы.
  3. runtime. Зависимость не нужна для компиляции, но нужна для выполнения.
  4. test. Зависимость не нужна для нормальной работы приложения, а нужна только для компиляции и запуска тестов.
  5. system. Область аналогична provided за исключением того, что содержащий зависимость JAR указывается явно. Артефакт не ищется в репозитории.
  6. import (начиная с версии Maven 2.0.9) используется только с зависимостью типа pom в секции <dependencyManagement>. Зависимости текущего POM заменяются на зависимости из указанного POM.

Приведение проекта к виду Maven

Проект, поддерживающийся с помощью Maven, должен удовлетворять некоторым условиям для возможности его чтения утилитой, последующего анализа и возможности сборки. Это накладывает некоторые ограничения на структуру каталогов и требует дополнительных действий, если проект изначально имеет отличную структуру.[23]

Для того, чтобы Maven распознал проект, как подлежащий обработке, он должен содержать установленную структуру каталогов. Все файлы с исходным кодом должны находиться по относительному пути «\src\main\java»[12].

Файл конфигурации web-проекта web.xml должен находиться в каталоге «\src\main\webapp\WEB-INF»[12].

Файл конфигурации Maven-проекта pom.xml должен находиться в корневом каталоге проекта. В нём согласно его предназначению могут быть указаны удаленный репозиторий, плагины для создания архивов, плагин компилятора и прочее. Для web-проекта также необходимо добавлять дополнительные зависимости, как например javaee.jar.

Таким образом, выходной файл конфигурации веб-проекта, согласованный с 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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mkyong</groupId>
  <artifactId>servletdemo</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>servletdemo</name>
  <url>http://maven.apache.org</url>

  <repositories>
    <repository>
      <id>java.net</id>
      <url>http://download.java.net/maven/2</url>
    </repository>
  </repositories>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <configuration>
          <webResources>
            <resource>
              <directory>${basedir}/src/main/java</directory>
              <targetPath>WEB-INF/classes</targetPath>
              <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
                <include>**/*.css</include>
                <include>**/*.html</include>
              </includes>
            </resource>
          </webResources>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.6</source>
          <target>1.6</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

После выполнения всех указанных требований Maven-проект готов для выполнения фаз жизненного цикла, таких, как компиляция, сборка архива и генерация документации[24].

Пример выходного лога сообщений при выполнении команды mvn war:war:

E:\workspace\servletdemo>mvn war:war
[INFO] Scanning for projects...
.......
[INFO] Processing war project
[INFO] Copying webapp resources[E:\workspace\servletdemo]
[INFO] Webapp assembled in[47 msecs]
[INFO] Building war: E:\workspace\servletdemo\target\servletdemo-1.0-SNAPSHOT.war
[INFO] -----------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] -----------------------------------------------

Взаимодействие со средами разработки

Для некоторых интегрированных сред разработки Maven содержит плагины, позволяющие управлять жизненным циклом, выполняя команды при помощи интерфейса IDE. Список таких сред разработки включает Eclipse (через плагин M2eclipse), IntelliJ IDEA, NetBeans, JBuilder, JDeveloper (версия 11.1.2), MyEclipse, Emacs[25]

Эти плагины обеспечивают также возможность удобно редактировать POM или использовать POM для полного описания зависимостей проекта для нужд используемого IDE.

Примечания

  1. Архивированная копия (недоступная ссылка). Дата обращения: 26 февраля 2012. Архивировано 19 февраля 2012 года. POM
  2. Maven — What is Maven?. Дата обращения: 25 февраля 2012. Архивировано 21 февраля 2012 года.
  3. Apache Maven Community. Apache Maven Compiler Plugin. Apache Maven Project. Дата обращения: 18 декабря 2015. Архивировано 13 декабря 2015 года.
  4. Исторический архив версий Maven Архивная копия от 11 февраля 2012 на Wayback Machine.
  5. Официальная страница Maven 1.x Архивировано 15 февраля 2012 года.
  6. 6,0 6,1 Apache Maven Foundation. Maven Releases History. Apache Maven Docs. Дата обращения: 20 декабря 2015. Архивировано 19 декабря 2015 года.
  7. 7,0 7,1 Apache Foundations. Минимальное содержание POM-файла. Apache Maven Project. Дата обращения: 6 октября 2007. Архивировано 19 ноября 2017 года.
  8. Super POM Архивная копия от 19 ноября 2017 на Wayback Machine.
  9. Maven by Example Архивная копия от 15 сентября 2020 на Wayback Machine.
  10. Что такое Convention over Configuration?. Дата обращения: 28 октября 2016. Архивировано 14 сентября 2016 года.
  11. Apache Maven Foundation. Документация Maven. Архитипы.. Дата обращения: 18 декабря 2015. Архивировано 22 декабря 2015 года.
  12. 12,0 12,1 12,2 Официальная страница Apache Maven: структура каталогов Архивная копия от 21 февраля 2012 на Wayback Machine.
  13. Maven Build Lifecycle Reference Архивная копия от 17 ноября 2017 на Wayback Machine.
  14. .NET Maven Plugin Архивная копия от 27 октября 2016 на Wayback Machine.
  15. Native Maven Plugin Архивная копия от 29 октября 2016 на Wayback Machine.
  16. NAR plugin Архивная копия от 20 декабря 2017 на Wayback Machine.
  17. Maven Compiler Plugin Архивная копия от 15 декабря 2017 на Wayback Machine.
  18. Maven — Доступные плагины Архивная копия от 24 июля 2017 на Wayback Machine.
  19. Maven Central Repository Архивная копия от 26 апреля 2020 на Wayback Machine.
  20. Maven search engine Архивная копия от 26 апреля 2020 на Wayback Machine.
  21. Таблица сравнения Архивировано 23 ноября 2012 года.
  22. Apache Maven Foundation. Maven Documentation. Введение в механизм зависимостей. Дата обращения: 18 декабря 2015. Архивировано 20 декабря 2015 года.
  23. Как преобразовать web-проект к Maven-проекту Архивная копия от 21 февраля 2012 на Wayback Machine.
  24. Apache Foundation. Building a Project with Maven. Apache Maven Documentation. Дата обращения: 21 декабря 2015. Архивировано 3 января 2016 года.
  25. EmacsWiki: Malabar Mode Архивная копия от 3 ноября 2013 на Wayback Machine.

Ссылки

  • Выговский Леонид. Установка maven-репозитория Artifactory (5 января 2010). — В статье дается подробная инструкция по установке maven-репозитория на сервере приложенй Glassfish или контейнере сервлетов Apache Tomcat.. Дата обращения: 5 января 2010. Архивировано 29 февраля 2012 года.