Что такое Maven: назначение, преимущества и недостатки
Скрипт build.bat собирает проект на Windows командой javac -cp "lib/gson.jar;lib/slf4j-api.jar" -d out src/com/example/*.java. Тот же скрипт, скопированный в build.sh на Linux, падает с error: package com.google.gson does not exist: в Linux элементы classpath разделяются двоеточием, а не точкой с запятой. Maven убирает такие проблемы целиком: один файл pom.xml и одна команда mvn package работают одинаково в любой операционной системе.
Maven (Apache Maven) — это инструмент для сборки Java-проектов и управления их зависимостями. Он скачивает нужные библиотеки, компилирует код, запускает тесты, упаковывает результат в jar или war и генерирует документацию. Проект описывается декларативно в файле pom.xml: вы указываете, что нужно получить, а как это сделать, Maven знает сам благодаря стандартным соглашениям.
Что такое Maven простыми словами
Простыми словами, Maven — это «автоматический сборщик» Java-проекта: вы один раз описываете проект и его библиотеки в pom.xml, а дальше любая команда вроде mvn package сама скачает зависимости, скомпилирует код, прогонит тесты и соберёт готовый jar. Ручные скрипты и папка lib с jar-файлами больше не нужны.
Maven разрабатывается фондом Apache Software Foundation, написан на Java и распространяется под лицензией Apache License 2.0. Первая версия вышла в 2004 году. Название взято из идиша и означает «знаток, собиратель знаний».
Без инструмента сборки маленький проект можно собрать вручную через javac и jar. Но с ростом проекта команда сборки становится очень длинной, её записывают в bat/sh-скрипт, а такие скрипты зависят от платформы, их нужно поддерживать вручную и копировать между проектами. Maven решает эту задачу по-другому: вместо описания шагов сборки он опирается на принцип convention over configuration («соглашения важнее конфигурации»). Если код лежит в стандартных каталогах, настраивать почти ничего не нужно:
my-app/
├── pom.xml # описание проекта
├── src/
│ ├── main/
│ │ ├── java/ # исходный код
│ │ └── resources/ # ресурсы (properties, xml, ...)
│ └── test/
│ └── java/ # тесты
└── target/ # результат сборки (создаёт Maven) Какие задачи решает Maven
Maven закрывает весь путь от исходного кода до готового артефакта: скачивание библиотек, компиляция, запуск тестов, упаковка в jar/war, установка в локальный репозиторий, публикация и генерация отчётов. Всё это запускается одной командой и одинаково выполняется на компьютере разработчика и на CI-сервере.
- Управление зависимостями — библиотеки и их собственные зависимости скачиваются автоматически по координатам из
pom.xml. - Единый процесс сборки — этапы сборки стандартизированы, поэтому
mvn testилиmvn packageработают в любом Maven-проекте. - Стандартная структура проекта — разработчик, впервые открывший чужой Maven-проект, сразу знает, где лежат код, ресурсы и тесты.
- Автоматизация на сервере — Jenkins, GitHub Actions, GitLab CI запускают ту же команду, что и разработчик.
- Отчёты и проверки качества — документация Javadoc, покрытие тестами, статический анализ подключаются плагинами.
- Многомодульные проекты — один родительский
pom.xmlсобирает несколько связанных модулей в правильном порядке.
Ключевые понятия Maven
Чтобы работать с Maven, достаточно семи понятий: POM, артефакт, GAV-координаты, репозиторий, зависимость, жизненный цикл и плагин. Ниже каждое объяснено в одну строку, а подробный разбор — в отдельных уроках модуля, ссылки на них приведены в таблице.
| Понятие | Что это | Пример | Подробнее |
|---|---|---|---|
| POM (Project Object Model) | Описание проекта в файле pom.xml: координаты, зависимости, плагины, настройки сборки | pom.xml в корне проекта | Файл pom.xml в Maven |
| Артефакт | Любой файл, который Maven создаёт или скачивает: jar, war, pom, исходники, Javadoc | gson-2.11.0.jar | Виды репозиториев в Maven |
| GAV-координаты | Тройка groupId, artifactId, version, однозначно задающая артефакт | com.google.code.gson:gson:2.11.0 | Файл pom.xml в Maven |
| Репозиторий | Хранилище артефактов: локальное (~/.m2/repository), центральное (Maven Central) или корпоративное | https://repo.maven.apache.org/maven2 | Виды репозиториев в Maven |
| Зависимость | Сторонняя библиотека, объявленная в pom.xml по GAV-координатам | JUnit, Jackson, драйвер БД | Раздел ниже |
| Жизненный цикл | Упорядоченная последовательность фаз сборки; запуск фазы выполняет и все предыдущие | compile → test → package → install | Жизненный цикл сборки |
| Плагин | Модуль, который выполняет реальную работу; фазы жизненного цикла лишь вызывают цели (goals) плагинов | maven-compiler-plugin, maven-surefire-plugin | Использование плагинов в Maven |
Важная деталь архитектуры: сам Maven почти ничего не умеет. Компиляцию выполняет maven-compiler-plugin, тесты — maven-surefire-plugin, упаковку — maven-jar-plugin. Maven лишь знает, какой плагин вызвать на какой фазе.
Минимальный pom.xml и первая сборка
Минимальный рабочий pom.xml содержит версию модели POM и GAV-координаты проекта; версию Java задаёт свойство maven.compiler.release. Всё остальное — каталоги, тип упаковки jar, стандартные плагины — Maven берёт из встроенного родительского Super POM.
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>com.examclouds</groupId>
<artifactId>hello-maven</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.release>21</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project> Если положить класс в src/main/java и выполнить в корне проекта команду сборки, Maven скомпилирует код, запустит тесты (если они есть) и создаст jar-файл:
mvn package # Вывод (фрагмент):
[INFO] Building jar: /home/user/hello-maven/target/hello-maven-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------ Для Java 17 замените 21 на 17. Если установленный JDK старше указанной версии (например, JDK 17 при release 21), сборка остановится с ошибкой Fatal error compiling: error: release version 21 not supported. Что означают теги packaging, build, dependencies и суффикс -SNAPSHOT, разобрано в уроке Файл pom.xml в Maven.
Нюанс: release вместо source/target
В старых статьях версию Java задают парой maven.compiler.source и maven.compiler.target. Она проверяет только синтаксис, но не API. Код List.of(1, 2, 3).getFirst() (метод появился в Java 21) при source/target 17 на JDK 21 успешно скомпилируется, а на Java 17 упадёт уже при запуске: java.lang.NoSuchMethodError: 'java.lang.Object java.util.List.getFirst()'. С maven.compiler.release 17 та же ошибка обнаруживается при компиляции: cannot find symbol: method getFirst(). Поэтому для Java 9+ используйте release.
Зависимости: что это и зачем
Зависимость в Maven — это сторонняя библиотека, которую проект использует и которую достаточно объявить в pom.xml по GAV-координатам. Maven сам скачает её из Maven Central в локальный репозиторий ~/.m2/repository и добавит в classpath при компиляции, тестах и упаковке.
<dependencies>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.11.0</version>
</dependency>
</dependencies> Вместе с библиотекой Maven подтягивает и её собственные зависимости — они называются транзитивными. Элемент <scope> уточняет, где библиотека нужна: по умолчанию (compile) — везде, а test — только для тестов. Полное дерево зависимостей проекта показывает команда:
mvn dependency:tree Актуальные версии и Maven Wrapper
Актуальная стабильная ветка — Maven 3.9.x; для её запуска нужна Java 8 или новее, а версию Java для компиляции проекта задаёт pom.xml. Следующая мажорная версия, Maven 4, развивается параллельно; текущий статус и номер последнего релиза смотрите на странице загрузки Apache Maven.
Ещё два факта, которые часто расходятся со старыми статьями:
- С января 2020 года Maven Central принимает запросы только по HTTPS. Адрес вида
http://repo1.maven.org/maven2в старомpom.xmlилиsettings.xmlприводит к ошибке501 HTTPS Required. - Начиная с Maven 3.8.1 внешние репозитории по HTTP по умолчанию блокируются (встроенное зеркало
maven-default-http-blocker).
Как установить Maven и проверить установку командой mvn -version, описано в уроке Руководство по установке Maven.
Maven Wrapper: одна версия Maven для всей команды
Команда mvn wrapper:wrapper добавляет в проект скрипты mvnw и mvnw.cmd и файл .mvn/wrapper/maven-wrapper.properties с версией Maven. После этого проект собирают командой ./mvnw package (в Windows — mvnw.cmd package): нужная версия Maven скачается автоматически, ставить Maven вручную не нужно. Скрипты и каталог .mvn коммитят в Git — так CI-сервер и все разработчики собирают проект одной и той же версией.
Преимущества Maven
Главные преимущества Maven — независимость сборки от операционной системы, автоматическое управление зависимостями, единая структура проектов и огромная экосистема библиотек и плагинов. Именно поэтому Maven остаётся одним из двух стандартных инструментов сборки в мире Java наряду с Gradle.
- Независимость от операционной системы. Сборка проекта выполняется в Windows, Linux и macOS по одному и тому же файлу
pom.xml— без отдельных bat и sh-скриптов. - Управление зависимостями. Редкий проект пишется без сторонних библиотек, а те, в свою очередь, используют другие библиотеки разных версий. Maven строит полное дерево зависимостей и разрешает конфликты версий автоматически: если одна библиотека встречается несколько раз, выбирается версия, ближайшая к проекту в дереве (nearest wins). Это позволяет контролировать конфликты и при необходимости легко переходить на новые версии библиотек.
- Сборка из командной строки. Одна команда (
mvn package,mvn verify) запускает всю сборку — это нужно для автоматической сборки проекта на CI-сервере. - Хорошая интеграция со средами разработки. IntelliJ IDEA, Eclipse (плагин m2e) и VS Code (Extension Pack for Java) открывают
pom.xmlкак проект: сами подтягивают зависимости, настраивают каталоги и запускают фазы сборки. Файлы настроек конкретной IDE хранить в репозитории не нужно. - Декларативное описание проекта (POM). В
pom.xmlописывается, что нужно получить, а не последовательность шагов. Описание легко читать и переносить между проектами. - Огромный, поддерживаемый в актуальном состоянии репозиторий артефактов. В Maven Central опубликованы практически все открытые Java-библиотеки; ими пользуются и Gradle, и другие инструменты сборки.
- Модульная архитектура и огромное количество плагинов. Компиляция, тесты, упаковка, анализ кода, генерация документации и Docker-образов — всё подключается плагинами (подробнее — в уроке Использование плагинов в Maven).
- Единые соглашения. Одинаковая структура каталогов и одинаковые команды во всех проектах снижают порог входа в новый проект.
Недостатки Maven
Основные недостатки Maven — сложность освоения, «неявное» поведение из-за соглашений по умолчанию, многословный XML и трудная диагностика ошибок. Кроме того, для нестандартной логики сборки Maven менее гибок, чем Gradle, а инкрементальная сборка у него медленнее.
- Сложность освоения. Чтобы уверенно работать с Maven, нужно понимать жизненный цикл, плагины, область видимости зависимостей и наследование POM.
- Неочевидность в некоторых моментах. Многое происходит «за кадром»: каждый
pom.xmlнаследует настройки Super POM, а плагины привязаны к фазам по умолчанию. Увидеть итоговую конфигурацию помогает командаmvn help:effective-pom. - Огромное количество плагинов. Для одной задачи часто существует несколько плагинов разного качества и степени поддержки — трудно сориентироваться и выбрать.
- Трудно разобраться, если что-то пошло не так. Сообщения об ошибках бывают длинными и неинформативными. Подробности дают флаги
-e(стек исключения) и-X(отладочный вывод). - Нужен доступ в интернет или собственный репозиторий артефактов. Первая сборка скачивает зависимости и плагины. Офлайн-режим
mvn -oработает, только если всё нужное уже лежит в локальном репозитории. - Многословный XML. Даже простая зависимость занимает 5 строк, а большой
pom.xmlлегко разрастается до сотен строк. - Ограниченная гибкость. Нестандартные шаги сборки приходится реализовывать через плагины или писать собственный плагин, тогда как в Gradle логику можно описать прямо в скрипте сборки.
Maven, Ant или Gradle: сравнение
Ant, Maven и Gradle — три основных инструмента сборки для Java. Ant описывает шаги сборки вручную и не управляет зависимостями, Maven задаёт стандартный процесс и структуру через декларативный pom.xml, а Gradle сочетает соглашения Maven с гибкостью скриптов на Groovy или Kotlin и быстрой инкрементальной сборкой.
| Критерий | Ant | Maven | Gradle |
|---|---|---|---|
| Год появления | 2000 | 2004 | 2012 (версия 1.0) |
| Файл сборки | build.xml (XML) | pom.xml (XML) | build.gradle / build.gradle.kts (Groovy или Kotlin DSL) |
| Подход | Императивный: вы описываете каждый шаг | Декларативный: описываете проект, шаги задаёт жизненный цикл | Декларативный с возможностью писать логику в скрипте |
| Управление зависимостями | Нет встроенного (подключается Apache Ivy) | Встроенное, Maven Central | Встроенное, использует те же Maven-репозитории |
| Стандартная структура проекта | Нет | Строгая (src/main/java и т.д.) | Та же, что у Maven, но легко меняется |
| Скорость повторной сборки | Зависит от скрипта | Средняя; есть параллельная сборка модулей (-T) | Высокая: инкрементальная сборка, кэш сборки, демон |
| Порог входа | Низкий для простых задач | Средний | Выше: нужно знать DSL |
| Где встречается сегодня | Старые (legacy) проекты | Корпоративные проекты, Spring Boot, библиотеки | Android (официальный сборщик), Spring Boot, крупные многомодульные проекты |
Когда выбирать Maven. Maven — хороший выбор, если проект укладывается в стандартный процесс «скомпилировать — протестировать — упаковать», важны предсказуемость и единообразие, а в команде разный уровень опыта. Gradle выигрывает в больших многомодульных проектах, где критична скорость сборки, и в Android-разработке. Новичку разумно начинать с Maven: его соглашения и терминологию (GAV, scope, репозитории) использует и Gradle.
Часто задаваемые вопросы
Maven — это фреймворк или библиотека?
Ни то, ни другое: Maven — это инструмент сборки, который запускается из командной строки или IDE. В итоговый jar приложения он не попадает и в коде не используется, в отличие от фреймворков вроде Spring.
Нужно ли устанавливать Maven, если IntelliJ IDEA уже умеет собирать Maven-проекты?
Для работы только в IDE — нет: IntelliJ IDEA и Eclipse содержат встроенный Maven. Отдельная установка или Maven Wrapper нужны, чтобы запускать mvn в терминале и на CI-сервере. Пошаговая установка — в уроке Руководство по установке Maven.
Почему старый проект не собирается с ошибкой «501 HTTPS Required»?
В pom.xml или settings.xml указан адрес Maven Central по HTTP, а с января 2020 года он работает только по HTTPS. Замените адрес на https://repo.maven.apache.org/maven2 или удалите явное объявление центрального репозитория — Maven подключает его сам.
Можно ли собрать Maven-проект без интернета?
Да, если все зависимости и плагины уже скачаны в локальный репозиторий ~/.m2/repository: запустите сборку с флагом -o (offline). Заранее скачать всё нужное помогает mvn dependency:go-offline. В компаниях без доступа к интернету используют корпоративный репозиторий — см. урок Виды репозиториев в Maven.
Комментарии