W3docs

Введение в Java Maven

Что такое Maven, как он собирает Java-проекты, как установить и запускать команды mvn.

Maven — стандартный инструмент автоматизации сборки и управления зависимостями для Java. Он превращает проект в декларативное описание — что это такое, от чего зависит, как собирается — и затем выполняет сборку за вас. Вместо того чтобы вручную управлять JAR-файлами и флагами javac, вы декларируете свои потребности в одном файле, а Maven загружает зависимости, компилирует, тестирует и упаковывает ваш код через предсказуемый, воспроизводимый жизненный цикл.

POM: проект как данные

Каждый проект Maven описывается файлом pom.xml (Project Object Model). Он идентифицирует проект тремя координатами — groupId, artifactId и version (вместе «GAV») — и перечисляет нужные библиотеки. Та же схема координат именует ваш проект и каждую зависимость, что позволяет Maven находить артефакты в репозитории.

<project xmlns="http://maven.apache.org/POM/4.0.0">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.example</groupId>
  <artifactId>shop-app</artifactId>
  <version>1.0.0</version>
  <packaging>jar</packaging>

  <properties>
    <maven.compiler.release>21</maven.compiler.release>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>6.1.0</version>
    </dependency>
  </dependencies>
</project>

Элемент <packaging> указывает Maven, что создавать (jar, war, pom). Блок <properties> содержит переиспользуемые значения — здесь это целевая версия Java для компилятора. POM расширяется, охватывая плагины, профили и наследование; в главе Maven POM эти части разобраны подробно.

Зависимости и транзитивный classpath

Вы перечисляете только свои прямые зависимости. Maven читает POM каждой из них и подтягивает всё, что нужно имтранзитивные зависимости, — автоматически формируя полный classpath. Объявление spring-web также принесёт spring-core, без явного указания.

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.17.0</version>
</dependency>

Каждая зависимость имеет scope, определяющий, когда она присутствует в classpath. Значение по умолчанию — compile — делает её доступной везде; test ограничивает только тестовым кодом; provided означает, что среда выполнения предоставит её сама. Подробнее об исключениях конфликтов версий и dependencyManagement — в разделе Maven dependencies.

ScopeВ compile classpathВ test classpathУпакованаТипичное применение
compile (по умолчанию)ДаДаДаОбычные библиотеки
providedДаДаНетServlet API, предоставляется в runtime
runtimeНетДаДаJDBC-драйверы
testНетДаНетJUnit, Mockito

Жизненный цикл сборки

Сборки Maven проходят через фиксированную последовательность фаз. Ключевые фазы стандартного жизненного цикла: validate, compile, test, package, verify, install и deploy. Запуск фазы запускает все предшествующие — mvn package сначала валидирует, компилирует и тестирует, а затем упаковывает. Фазы никогда не вызываются не по порядку.

mvn compile          # compile main sources
mvn test             # compile + run unit tests
mvn package          # compile + test + build the JAR/WAR
mvn install          # package + copy artifact into your local repository
mvn clean package    # delete target/ first, then build fresh

Каждая фаза привязана к одной или нескольким целям (goals), предоставляемым плагинами (например, compiler:compile привязана к фазе compile). Именно в плагинах выполняется реальная работа; жизненный цикл лишь упорядочивает её. В главе Maven build lifecycle рассматриваются все три встроенных жизненных цикла и привязка целей к фазам.

Репозитории

Maven получает артефакты из репозиториев. При сборке он сначала ищет в вашем локальном репозитории (~/.m2/repository) — кэше на вашем компьютере. При промахе загружает из удалённого репозитория — по умолчанию Maven Central — и сохраняет копию локально, чтобы следующая сборка была быстрой без сети. Команды часто добавляют приватный репозиторий для внутренних библиотек.

project pom.xml  →  local repo (~/.m2)  →  remote repo (Maven Central)
                     (cache hit?)            (download + cache)

Рабочий пример

Среда выполнения не имеет Maven в своём classpath, поэтому программа ниже моделирует ключевую механику Maven с помощью обычного JDK-кода: хранит небольшой POM в виде карты, разрешает транзитивное замыкание зависимостей (удаляя дублирующиеся артефакты) и проходит по жизненному циклу сборки, останавливаясь на запрошенной фазе. Конструкции здесь — GAV-координаты, транзитивное разрешение, упорядоченные фазы — точно соответствуют тому, что делает настоящий Maven.

java— editable, runs on the server

Что следует усвоить из запуска:

  • Проект и каждая зависимость именуются одним и тем же GAV-тройником, вот почему Project coordinates: com.example:shop-app:1.0.0 читается так же, как строка зависимости.
  • Объявлены только две зависимости, но разрешённый classpath содержит четыре JAR — spring-core и jackson-annotations были подтянуты транзитивно, точно как это делает Maven.
  • Множество seen гарантирует, что каждый артефакт появится один раз; это дедупликация Maven, предотвращающая попадание общей библиотеки в classpath дважды.
  • Executing: mvn package выполняет validate, compile и test перед package, а затем останавливается — запуск фазы всегда запускает все предшествующие фазы по порядку.
  • Сборка останавливается на package и никогда не достигает install, отражая то, как запрошенная цель ограничивает продвижение жизненного цикла.

Когда стоит использовать Maven

Maven отлично подходит для стандартных Java и JVM-проектов: его соглашения «convention over configuration» (исходники в src/main/java, тесты в src/test/java, результаты в target/) означают, что новый участник может собрать любой Maven-проект одинаковым способом. Его декларативный XML легко читается и сравнивается, а поддержка в IDE зрелая. Компромисс — многословность и ограниченная гибкость для нестандартных сборок. Там, где нужны скриптовые, сильно кастомизированные сборки, распространённой альтернативой является Gradle — он использует программируемый скрипт сборки вместо декларативного XML, но охватывает ту же область: GAV-координаты, транзитивные зависимости и граф задач (вместо фаз).

Следующие шаги

  • Maven POM — полная структура pom.xml, включая плагины и наследование.
  • Maven dependencies — области видимости, исключения и разрешение конфликтов версий в деталях.
  • Maven build lifecycle — все фазы, три жизненных цикла и привязка целей.
  • Gradle introduction — скриптовая альтернатива Maven.

Практика

Практика
Что происходит в Maven при запуске 'mvn package'?
Что происходит в Maven при запуске 'mvn package'?
Was this page helpful?