В новом переводе от команды Spring АйО рассматриваются основные изменения, которые ждут нас в новой версии Maven. Изменения затронули performance, POM, новый тип упаковки, улучшения для подпроектов и много другое.
Maven существует уже более 20 лет и остаётся самым широко используемым инструментом сборки в мире Java. На протяжении этих лет Maven сохранял обратную совместимость, особенно в отношении POM-файла с моделью версии 4.0.0.
Комментарий от эксперта Spring АйО, Михаила Поливахи
Здесь наверное стоит пояснить, что версия Maven != что и версия формата POM файла. Поскольку сам Maven, как build tool, является Java программой, у него тоже есть версии. Сам Maven уже очень долгие годы находился на версии 3.x:
https://maven.apache.org/docs/history.html
Версия же POM файла это лишь версия формата файла pom.xml
. Вы её устанавливаете в теге modelVersion
. И версия формата POM файла уже тоже достаточно долго была 4.0.0.
POM-файл выполняет две функции. Во-первых, он содержит всю информацию и конфигурацию, необходимую для сборки артефакта. После создания артефакта эта информация больше не имеет значения. Во-вторых, POM также включает сведения, например о зависимостях, которые требуются другим проектам, зависящим от этого артефакта. Такие проекты, которые зависят от нашего артефакта, называются «потребителями» (consumers).
Эти две функции сделала Maven не просто инструментом, а целой экосистемой, где многие компоненты — включая Maven Central, инструменты сборки и среды разработки — зависят от структуры POM. Поэтому любое изменение схемы POM требует либо адаптации со стороны всех участников экосистемы, либо отказа от поддержки схемы вообще. В результате синтаксис POM оказался зафиксированным и не поддающимся изменению.
«Схема сборки Maven по сути влита в янтарь и не даёт нам развиваться: мы обречены навсегда оставаться на минорных релизах Maven 3, не в состоянии реализовать улучшения, которые требуют серьёзного обновления схемы POM…»
— Эрве Бутеми (Javaadvent 2021)
Чтобы Maven мог развиваться, необходимо отделить информацию, нужную для сборки, от информации, требуемой потребителями — при этом не разрушив экосистему. Maven 4 готовит почву для этого и многого другого.
В этой статье представлены и объяснены основные изменения, появившиеся в Maven 4, сгруппированные по темам.
Требуемая версия Java
Maven 4 требует Java 17. Это позволяет разработчикам Maven использовать новые возможности языка и улучшения платформы.
Важно: Java 17 требуется только для запуска Maven! Вы по-прежнему можете компилировать проекты под более старые версии Java, используя прежнюю конфигурацию плагина компилятора. Если необходимо использовать другой JDK или собирать под другую версию Java, см. руководство по Toolchains или статью Introduction to Maven Toolchains от одного из мейнтейнеров Maven, Маартена Мюлдерса.
Комментарий от эксперта Spring АйО, Михаила Поливахи
Напоминиаем, Maven - это просто Jar с набором обвязки вокруг
Изменения в POM
Consumer POM
Maven 4 генерирует “облегчённый” consumer POM, исключая из него информацию о сборке, не нужную потребителям, и публикует его в удалённый репозиторий. Сам файл pom.xml, использованный для сборки проекта, при этом не разворачивается.
Модель версии 4.1.0
Maven 4 обновляет версию модели POM до 4.1.0, определяя пространство имён (XML namespace) http://maven.apache.org/POM/4.1.0. В этой версии добавлены новые элементы и атрибуты, а некоторые устаревшие отмечены как deprecated. Чтобы не нарушать работу экосистемы, эта версия применяется только для build POM, тогда как consumer POM по-прежнему использует версию 4.0.0. Maven генерирует consumer POM во время сборки на основе build POM.
Примечание: Maven 4 продолжает поддерживать проекты с моделью версии 4.0.0. Обновлять ваши POM-файлы до 4.1.0 не требуется, если вы не планируете использовать новые функции.
Модули теперь называются подпроектами
Проект Maven — это любой Java-проект, собираемый с помощью Maven. В корневом каталоге проекта Maven, как минимум, находятся папка с исходным кодом src и файл pom.xml. Maven-проект может содержать другие проекты Maven в подкаталогах, каждый из которых имеет собственный файл pom.xml. Каждый проект в таком подкаталоге называется подпроектом.
Пример: Проект A содержит подкаталог с собственным POM-файлом для проекта B. В этом случае говорят, что B — это подпроект A.
Однако Maven не собирает подпроекты автоматически, если они не указаны в корневом POM-файле. Ранее это делалось путём перечисления всех подпроектов в разделе <modules> родительского POM-файла. Проекты, содержащие хотя бы один подпроект, называются мульти-модульными проектами (multi-module projects), а проекты без подпроектов — одномодульными (single-module projects). С момента появления модульной системы Java Platform Module System в Java 9 термин модуль стал вызывать путаницу в сообществе Maven.
В Maven 4 от этого отказались: термин “модуль” переименован в термин “проект” (project), а “подмодуль” — в подпроекты (sub-project). Модель версии 4.1.0 включает новый элемент <subprojects>
, аналогичный устаревшему (но всё ещё поддерживаемому) элементу <modules>
.
Примечание: используйте термины мультипроектная структура и однопроектная структура, чтобы различать проекты Maven с подпроектами и без них.
Новый тип упаковки: bom
Maven 4 вводит новый тип упаковки bom для предоставления спецификации состава проекта (Bill of Materials, BOM). Это позволяет явно различать родительские POM-файлы и BOM-файлы, управляющие зависимостями. Новый тип доступен только для build POM в модели версии 4.1.0 и выше, но во время сборки Maven генерирует совместимый с Maven 3 consumer POM.
Комментарий от эксперта Spring АйО, Михаила Поливахи
Поясним, чтобы избежать путаницы. В Maven уже давно можно работать с BOM, но делается это путём того, что создается pom.xml
с одноименным packaging type-ом, т.е. с "pom".
Проблема в том, что "pom" это как бы общий packaging тип как для parent pom, так и для bom, хотя эти две вещи далеко не обязательно используются вместе (Например, spring-boot-dependencies не обязательно подключать как parent, её можно импортировать тоже с типом "pom" в секции dependencyManagement
).
Иными словами, мейнтейнеры просто устранили путаницу в терминологии.
Само по себе это изменение не добавило новых фич, но оно дало возможность реализовать ряд нововведений, смотрите ниже.
Пример можно найти по ссылке выше или в демонстрации от мейнтейнера Maven Карла Хайнца Марбайзе на IntelliJ IDEA Conf 2024.
Примечание: из нового - в Maven 4 стало возможно исключать зависимости, объявленные в BOM, с помощью уже существующего элемента <exclusions>. Кроме того, в Maven 4 можно импортировать BOM-файлы с использованием классификатора. Поэтому команда Maven рекомендует генерировать BOM-файлы как артефакты с классификатором, используя элемент <bomClassifier>
. Это означает, что импортируемый BOM не должен быть частью текущей сборки, а должен быть доступен извне до начала сборки. Другими словами: импортировать следует только внешние BOM-файлы. Именно поэтому Maven 4.0 будет выдавать предупреждение, если загружаемый BOM является частью текущего мультипроектного билда. В будущем это поведение, скорее всего, изменится, и такая сборка будет завершаться с ошибкой.
Сравнение build POM и consumer POM
Следующая таблица даёт общее представление о том, какая информация содержится в каком типе POM при использовании Maven 4.
Примечания:
Колонка «consumer POM» не относится к артефактам типа pom, поскольку такие артефакты изначально предназначены для хранения информации о сборке, например, конфигурации плагинов.
Некоторые данные, связанные со сборкой, которые пока ещё присутствуют в consumer POM, в будущем, возможно, будут доступны только в build POM.
Content |
Build POM |
Consumer POM |
Model version |
4.1.0 |
4.0.0 |
3rd party dependency information |
✅ |
✅ |
POM properties |
✅ |
❌ |
Plugin configuration |
✅ |
❌ |
Repository information |
✅ |
✅ |
Project information / environment settings |
✅ |
✅ |
Deployment to remote repository |
✅ |
✅ |
Предупреждение
В редких случаях Maven 4 может сгенерировать consumer POM на основе версии 4.1.0, например, когда профили, основанные на условиях (см. ниже), невозможно преобразовать в формат версии 4.0.0. В таких ситуациях Maven выведет предупреждение.
Объявление корневого каталога и свойства директорий
Каждый раз при запуске сборки Maven должен определить корневой каталог проекта, чтобы определить такие параметры, как родительский проект, структура каталогов и т. д. Чтобы помочь Maven найти корневую папку, можно создать каталог .mvn в корне проекта. Этот каталог предназначен для хранения конфигурации, специфичной для проекта, например, файлов maven.config или jvm.config, и поэтому ранее также считался корневым.
В Maven 4 появился второй способ явно определить корневую папку. Версия модели 4.1.0, применяемая для build POM, добавляет логический атрибут root в элемент <project>
. Когда этот атрибут установлен в true
(по умолчанию — false
), каталог, содержащий данный POM-файл, считается корневым.
Другой проблемой, связанной с корневой директорией, было то, что до Maven 4 не существовало официального свойства, позволяющего ссылаться на корневую папку в POM-файлах — например, при указании пути к файлу checkstyle-suppressions.xml для плагина Checkstyle. В Maven 4 появились официальные свойства, позволяющие ссылаться на корневой каталог в конфигурации POM. Следующая таблица показывает эти свойства.
Свойство |
Scope |
Definition |
Всегда |
|
Project |
.mvn folder or root attribute in pom |
No |
|
Session |
Current directory or --file argument |
Yes |
|
Session |
.mvn folder or root attribute in pom for the topDirectory project |
No |
Как видно, эти свойства различаются по своей области действия: project всегда относится к определению проекта Maven (можно интерпретировать это как POM-файлы), а session — к фактическому выполнению сборки Maven и представляет текущую рабочую директорию. Свойство rootDirectory
может содержать значение только в том случае, если либо определён каталог .mvn
, либо установлен атрибут root в значение true
. Однако, если оно определено, оно должно всегда иметь одно и то же значение для заданного проекта, тогда как значение свойства topDirectory
может изменяться в зависимости от точки выполнения.
Имейте в виду, что корневая директория всего проекта (если учитывать несколько подпроектов) отличается от базовой директории каждого подпроекта, доступной через свойство ${basedir}
для использования в POM-файлах. Это свойство всегда имеет значение.
Примечание: в прошлом некоторые пользователи использовали различного рода “хаки” для реализации свойств аналогичных rootDirectory
, в основном с помощью использования различных внутренних свойств Maven. Начиная с Maven 4, эти свойства были удалены или помечены как устаревшие. См. задачу JIRA MNG-7038 и соответствующий Pull Request для получения дополнительной информации.
Альтернативные синтаксисы POM
Хотя синтаксис consumer POM версии 4.0.0 зафиксирован, build POM должен иметь возможность развиваться. Это включает поддержку альтернативных синтаксисов благодаря появлению интерфейса ModelParser SPI (MNG-7836) в Maven 4. Он может быть реализован как расширение ядра и позволит использовать собственный синтаксис.
Одним из первых проектов, использующих эту возможность, является расширение Apache Maven Hocon Extension.
Улучшения для подпроектов
Автоматическое управление версиями
Maven 4 наконец реализует один из самых старых запросов на улучшение — автоматическое указание версии родительского проекта (MNG-624, создан в июле 2005 года и изначально планировался для Maven 2). Как и ожидалось, больше не требуется указывать версии родительского проекта в каждом подпроекте при использовании новой версии модели 4.1.0. Это также распространяется на зависимости между подпроектами одного проекта и ещё больше снижает необходимость обновления POM-файлов при выпуске новых версий.
<project xmlns="http://maven.apache.org/POM/4.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.1.0 http://maven.apache.org/xsd/maven-4.1.0.xsd">
<modelVersion>4.1.0</modelVersion>
<parent>
<groupId>my.parents.groupId</groupId>
<artifactId>my.parents.artifactId</artifactId>
</parent>
<artifactId>myOwnSubprojectArtifactId</artifactId>
<dependencies>
<dependency>
<groupId>the.dependent.subproject.groupId</groupId>
<artifactId>the.dependent.subproject.artifactId</artifactId>
</dependency>
</dependencies>
</project>
Полная поддержка CI-дружественных переменных
В версии Maven 3.5.0 была введена частичная поддержка CI-friendly переменных, таких как ${revision}, в POM-файлах. Однако для полноценной работы всё ещё требовалось использование плагина Flatten Maven Plugin. Начиная с Maven 4, дополнительный плагин больше не нужен — поддержка этих переменных теперь встроена полностью. Вы можете использовать переменные в качестве значений версий в конфигурации.
Пример
<groupId>my.groupId</groupId>
<artifactId>my.artifactId</artifactId>
<version>${revision}</version>
Значение для этой переменной необходимо задавать при запуске сборки, например, с помощью файла maven.config. В CI-пайплайнах это обычно делается через параметр, например:
mvn verify -Drevision=4.0.1
Мейнтейнер Maven Карл Хайнц Марбайзе приводит более развёрнутый пример в своей статье “Maven 4 - Part I - Easier Versions” (2024).
Улучшения и исправления в механизме сборки (Reactor)
Сборка проекта с несколькими подпроектами в Maven 3 может вызывать путаницу. Когда сборка подпроекта B, который зависит от подпроекта A, завершается с ошибкой, Maven 3 предлагает пользователю исправить ошибку и продолжить сборку с помощью --resume-from :<имяСбойногоПодпроекта>
. Но при этом сборка сразу снова завершается с ошибкой, потому что необходимый подпроект A не был пересобран (так как его не включили в сборку). Использование --also-make :<имяЗависимогоПодпроекта>
ранее не помогало, так как игнорировалось из-за давней ошибки MNG-6863, которая наконец-то исправлена в Maven 4!
Рекомендация: не используйте mvn clean install
для регулярных сборок. Вместо этого используйте mvn verify
!
Комментарий от эксперта Spring АйО, Михаила Поливахи
Позже мы выпустим отдельный перевод, где будет сказано, в чём причина
Для повышения удобства при возобновлении прерванной сборки теперь можно использовать --resume
или его короткую форму -r
, чтобы возобновить сборку с того подпроекта, на котором произошёл сбой. Это избавляет от необходимости вручную указывать имя сбойного подпроекта. Механизм сборки теперь также учитывает уже успешно собранные подпроекты, если общая сборка завершилась неудачно, и пропускает их при повторном запуске.
С выходом Maven 4 механизм также понимает сборки из подкаталогов (MNG-6118), что удобно, если вы хотите запускать инструменты (например, Jetty) только на определённых подпроектах, а не на всех. (См. статью Маартена Мюлдерса “What’s New in Maven 4” (2020) для примера).
Дополнительные улучшения
Дополнительные улучшения работы с подпроектами также повысят удобство повседневной работы с ними. Благодаря MNG-6754, все подпроекты теперь получают одинаковые метки времени в дистрибутиве артефактов, тогда как в Maven 3 у каждого подпроекта они были разными. Это упростит идентификацию архивов, принадлежащих одной сборке.
В Maven 3 при деплое проекта с несколькими подпроектами могла возникать ситуация, при которой успешно собранные подпроекты уже попадали в (локальный или удалённый) репозиторий, тогда как неудачные — нет. В Maven 4 это наконец изменено в соответствии с ожиданиями большинства пользователей: деплой выполняется только при успешной сборке всех подпроектов. Это означает, что теперь параметр deployAtEnd
по умолчанию имеет значение true
.
Изменения в рабочих процессах, жизненном цикле и во время выполнения
Обслуживание приложения (Application maintenance)
Как и в случае с каждым крупным обновлением, в Maven 4 проведено обширное техническое обслуживание, включая серьёзные обновления кода, API и зависимостей. Например, удалена система внедрения зависимостей Plexus Containers — она была устаревшей ещё с версии Maven 3.2 (2010)!
Обновления кода касаются не только использования новых возможностей Java, но и изменений, направленных на упрощение сопровождения проекта. Также были удалены функции, которые либо никогда не должны были работать, либо сохранялись в Maven 3 исключительно ради обратной совместимости — например, использование выражений ${pom.*}
.
Был обновлён и собственный Super POM Maven, в котором заданы новые версии плагинов Maven по умолчанию.
Примечание: из-за обновления версий плагинов по умолчанию поведение сборки может измениться, даже если вы сами ничего не меняли. Чтобы избежать неожиданных изменений, всегда указывайте фиксированные версии всех используемых плагинов. Так вы будете полностью контролировать процесс сборки. Maven 4 выдаст предупреждение, если вы полагаетесь на версии плагинов, определённые в Super POM.
Параметр “прерывание по уровню серьезности”
Maven 4 вводит параметр сборки “fail on severity”, который завершает сборку с ошибкой, если уровень серьёзности хотя бы одного лог-сообщения соответствует заданному аргументу.
Параметр можно использовать либо в полном виде (--fail-on-severity
), либо в сокращённой форме (-fos
). За параметром следует аргумент, указывающий уровень серьёзности логов, например WARN
.
Улучшения профилей
Попытка использовать несуществующий профиль в сборке приводит к её сбою, как показано в следующем примере командной строки:
> mvn compile -Pnonexistent
[ERROR] The requested profiles [nonexistent] could not be activated or deactivated because they do not exist.
Maven 4 вводит возможность использовать профили только если они существуют. Для этого был добавлен аргумент ?
к параметру профиля. При использовании такой формы сборка не завершится с ошибкой. Вместо этого будет дважды выведено информационное сообщение (в начале и в конце). Пример:
> mvn compile -P?nonexistent
[INFO] The requested optional profiles [nonexistent] could not be activated or deactivated because they do not exist.
[...]
[INFO] BUILD SUCCESS
[INFO] ----------------------------------------------------------------------------------------------------------------
[INFO] Total time: 0.746 s
[INFO] Finished at: 2024-12-14T13:24:15+01:00
[INFO] ----------------------------------------------------------------------------------------------------------------
[INFO] The requested optional profiles [nonexistent] could not be activated or deactivated because they do not exist.
Maven 4 также вводит более гибкие способы активации профилей с помощью активации по условиям. Подробности см. в задаче MNG-8286.
Изменения жизненного цикла
Переход от графа к дереву
В Maven 3 жизненный цикл представлял собой упорядоченный список, содержащий все фазы. В Maven 4 это изменено: теперь жизненный цикл определяется как дерево фаз. Это позволяет более точно управлять выполнением зависимых фаз. Например, фаза compile должна выполняться только после того, как зависимости, необходимые только для компиляции, достигнут состояния ready.
Также теперь можно пропускать фазы (в отличие от старой модели-графа/списка). Например, можно выполнить деплой артефакта (deploy), не устанавливая его в локальный репозиторий пользователя (install).
Для сохранения совместимости поведение по умолчанию практически не отличается от Maven 3. Чтобы действительно воспользоваться преимуществами древовидного жизненного цикла, необходимо включить параллельную сборку с помощью параметра -b concurrent. При его использовании зависимости обрабатываются на уровне фаз, а не целиком по проектам, как в Maven 3. Например, при запуске mvn verify
в обычной сборке проект будет выполняться до конца фазы verify, прежде чем начнёт собираться зависимый проект. В режиме concurrent зависимый проект может начать сборку сразу после того, как его зависимости достигнут состояния ready.
Фазы before и after, порядок исполнения
Теперь каждая фаза жизненного цикла имеет подфазы before: и after:, к которым можно привязывать плагины. Например, если вы хотите подготовить тестовые данные перед запуском интеграционных тестов, можно выполнить задачи во время фазы before:integration-test
.
Если этого недостаточно — например, если нужно выполнить несколько задач в рамках одной фазы — можно задать порядок исполнения внутри фазы, добавляя числовые индексы в квадратных скобках к названию фазы.
Пример:
before:integration-test[100]
before:integration-test[200]
Предупреждение: концептуальные фазы pre-* и post-*, которые были доступны только для отдельных фаз и имели непоследовательные названия, считаются устаревшими. Не используйте их! Это особенно важно, если вы привязываете плагин к фазе post-* в жизненном цикле, потому что соответствующая фаза pre-* может отсутствовать — например, привязка к process-resources вместо несуществующей фазы pre-compile.
Фазы all и each
Maven 4 вводит несколько новых фаз жизненного цикла — all
, each
, before:all
, after:all
, before:each и after:each
, — которые предоставляют пользователю более тонкий контроль над выполнением плагинов, особенно в многопроектных и параллельных сборках.
Фазы all и each выполняются для каждого проекта и подпроекта, но их области действия различаются:
Фаза each охватывает стандартные фазы жизненного цикла (validate, compile, test и т. д.) одного проекта или подпроекта. Она используется для задания поведения, которое должно выполняться вокруг сборки отдельного подпроекта.
Фаза all охватывает всю сборку проекта, включая его фазу each и фазы all дочерних подпроектов. Это удобно для логики, которая должна выполняться один раз на весь проект, при этом включая всю иерархию подпроектов.
Чтобы сделать эту модель более интуитивной — особенно для пользователей, знакомых с фреймворками тестирования — в Maven 4 также введены следующие фазы-хуки:
before:all
— выполняется перед любой другой фазой текущего проекта. В многопроектной сборке фазаbefore:all
родительского проекта выполняется перед фазами его подпроектов.after:all
— выполняется в самом конце сборки проекта. В многопроектной сборке фазыafter:all
подпроектов выполняются перед соответствующей фазой родителя.before:each
— выполняется перед каждой стандартной фазой жизненного цикла проекта, аafter:each
— после каждой фазы. Это особенно полезно для реализации общей логики подготовки и завершения работы вокруг каждой фазы.
Совместно эти новые фазы предоставляют мощную и понятную структуру для определения и настройки поведения сборки в сложных проектах Maven.
Плагины Maven, безопасность и инструменты
Плагины Maven
Как упоминалось ранее, в Maven 4 реализованы значительные обновления кода и API, что приводит к несовместимости с (очень) старыми плагинами Maven, которые не были обновлены с переходом на рекомендуемые API. Основные изменения в работе с плагинами включают:
полностью иммутабельную модель плагинов,
пересмотренный API плагинов.
Новый API предоставляет подсказки в рамках подготовки к работе с Maven 4. Их можно включить, передав в сборку аргумент:
-Dmaven.plugin.validation=verbose
Также при разработке плагинов рекомендуется использовать только официальные BOM-файлы Maven. Если плагин всё ещё зависит от устаревшего и теперь удалённого механизма внедрения зависимостей Plexus, он больше не будет работать. Необходимо перейти на JSR-330 — см. раздел Maven & JSR-330 для получения дополнительной информации.
Совет: если вы мейнтейните плагин Maven, протестируйте его с версией Maven 3.9.x. Обратите внимание на warning-и и обновите плагин соответствующим образом.
Улучшенное шифрование
Безопасность имеет значение, и хранение незашифрованных паролей — плохая практика. Шифрование паролей в Maven 3 имело несколько серьёзных недостатков и скорее представляло собой "запутывание", а не настоящее шифрование. В Maven 4 реализована полностью новая система шифрования, основанная на Maven Encryption (mvnenc) — отдельной CLI-утилите.
На текущий момент она предоставляет те же функции, что и в Maven 3 (см. Maven: Password Encryption), но с улучшениями, например возможностью дешифрования. Подробный обзор проблем в Maven 3 и решений в Maven 4 представлен в статье Handling sensitive data in Maven от мейнтейнера Maven Тамаша Червенака.
Maven Resolver
Maven Artifact Resolver — это библиотека для работы с репозиториями артефактов и разрешением зависимостей. В Maven 4 используется новая версия 2.0 этой библиотеки, содержащая более 150 исправлений, обновлений и улучшений. Например, добавлена реализация клиента HTTP на Java, благодаря повышению минимальной версии Java до JDK 17.
Одно из ключевых отличий по сравнению с Maven 3 заключается в том, что теперь резолвер скрыт за новым API Maven и больше не используется напрямую плагинами.
Maven Shell
Каждый раз при запуске команды mvn запускается весь процесс: инициализация Java, запуск Maven, загрузка конфигурации, выполнение задачи, завершение и выход — всё это при каждом запуске.
Для повышения производительности и снижения времени сборки можно использовать Maven Daemon (mvnd), который управляет пулом работающих процессов Maven.
С выходом Maven 4 появилась ещё одна альтернатива — “Maven Shell” (mvnsh), которая позволяет запускать один процесс Maven, работающий до тех пор, пока открыт shell.
Детальный Release Notes
Трекер задач Maven предоставляет полный список всех решённых задач в версии Maven 4.0.0.

Присоединяйтесь к русскоязычному сообществу разработчиков на Spring Boot в телеграм — Spring АйО, чтобы быть в курсе последних новостей из мира разработки на Spring Boot и всего, что с ним связано.
MEJIOMAH
Для чего в современном мире использовать maven когда есть gradle? У gradle куча плагинов, легко добавлять свои tasks в lifecycle и управлять общими правилами разработки на уровне компании. Также грейдл дружит с кешированием. От maven кажется остается только maven central и pom как дескриптор зависимостей.
headliner1985
Для того, чтобы не было бардака и кучи самописных скриптов на всех языках программирования мира. Кстати для скачивания сразу всех исходников и java доков в репозиторий нет простой команды, надо какой-то плагин в грэдле колхозить