Всем привет. Ранее я уже публиковал статьи (раз и два), где рассказывал о проблемах IDEA Maven плагина, основная из которых - это импорт проектов. И о своем решении Easy Maven - как получить информацию о проекте с помощью нативного Maven плагина. Теперь я бы хотел поговорить о запуске и отладке проектов в IDEA. С ними на самом деле похожая проблема. Чтобы это все работало, нужно импортировать в IDEA все настройки компилятора из билд файлов, чтобы среда разработки могла сама компилировать и запускать проект. Но это не так то просто - постоянно появляются новые параметры и возможности компиляторов, также для каждого из JVM языков (Java, Kotlin, Groovy, Scala и т.д.) есть свой компилятор со своими особенностями, annotation processors - которые надо дополнительно распознавать и загружать как jar-файлы с транзитивными зависимостями и импортировать в IDEA. Постоянно нужно за всем этим следить и нам опять приходить играть в догонялки. Только мы всегда находимся на шаг позади в роли отстающих и нужно тратить много ресурсов, чтобы заставить запускаться проект корректно из IDEA. Поэтому я решил и тут пойти другим путем - а зачем нам вообще все это делать и переносить настройки в IDEA, если мы можем просто выполнить Maven таск для соответствующего плагина - запуск теста или приложения? Поэтому я хотел бы остановиться на этом поподробнее и рассказать о своем решении.
Проблемы IDEA Maven plugin
Как уже было сказано выше, чтобы в IDEA корректно работала сборка приложения, а соответственно была возможность его запустить, нужно проделать объемную работу и перенести все настройки компилятора из билд файлов в настройки компилятора IDEA. Это одна из задач дефолтного Maven плагина. О том какая это непростая и трудоемкая операция, нам могут сказать release notes, для примера я бегло прошелся по двум последним мажорным релизам 25.1 и 25.2 и вот что там увидел:
Список проблем:
Annotation-Processor-configuration-is-misinterpreted
Support-annotationProcessorPathsUseDepMgmt-with-Maven-IntelliJ-compiler
MAVENOPTS-ignored-in-Intellij-2024.3
IDEA-shouldnt-try-to-build-test-classes-from-dependency-modules-when-I-run-test
Idea-2025.1-no-longer-honor-maven-compiler-plugins-compilerArg
Но несмотря на трудоемкость и потенциальные проблемы, это дает нам скорость запуска, т.к. IDEA хорошо умеет инкрементальную компиляцию в отличие от "голого" Maven и в итоге экономит наше время, также более тесная интеграция компилятора в IDEA делает для нас процесс запуска и отладки практически бесшовным, что мы даже не задумываемся о многих вещах, которые надо сделать прежде чем запустить отладку. Но обратная сторона медали это дополнительный слой абстракции, который приводит к проблемам описанным выше и который надо поддерживать на стороне IDEA Maven плагина.
Кроме того некоторые “новые” настройки компилятора требуют даже доработки IDEA, так например поддержка multi release потребовала достаточного большого времени на разработку и была внедрена относительно недавно.
В своем плагине изначально я пошел таким же путем, в процессе импорта проекта, переношу настройки компилятора из билд файлов в IDEA. И у меня появляются аналогичные проблемы:
Список проблем Easy Maven
Поэтому я и подумал, развивая дальше концепцию своего плагина, что “все есть файл таск”, а почему бы не делегировать процесс запуска и тестирования приложения соответствующим Maven плагинам, путем запуска их “тасков”? Собственно поэтому мой плагин так и называется - Easy Maven, что все что он делает это по сути делегирует работу соответствующему Maven плагину и интегрирует это со средой разработки.
А так ли нова эта идея и неужели никто до этого не додумался? На самом деле нет, все уже придумано до нас) Для начала обратим внимание на Gradle плагин, “неожиданно, но факт”, что он при запуске тестов, делегирует это Gradle “таску”, а не IDEA. Т.к. Gradle имеет свой Daemon и он также имеет билд кеш, поэтому преимущества IDEA компилятора сводятся на нет, и мы можем сразу запустить тест через систему сборки и освободиться от проблем озвученных выше. Но при этом Gradle плагин также переносит настройки компилятора в IDEA из билд файлов т.к. это может понадобится при запуске приложения.

В дефолтном IDEA Maven плагине также есть настройка, которая позволяет делегировать выполнение задач Maven:

Давайте включим ее и посмотрим что будет.
Запуск и отладка тестов
Начнем с запуска тестов. Будем запускать их, используя проект Zipkin. Это средний по размеру мульти-модульный Maven проект, к тому же он имеет открытый исходный код и достаточно тестов, на которых мы и будем проверять работу плагинов. Все проверки проводились на версии IDEA CE 25.2. Запустим тест - ‘getTraces_storedViaPost’ из модуля ‘zipkin-junit5’ дефолтным Maven плагином:

Выполнение теста в этом режиме, делегируется Maven Surefire Plugin. Но тест “упал”, потому что не удалось разрешить ряд зависимостей. Это Maven модули текущего проекта, от которых зависит выполняемый тест. Знакомая картина, не правда ли? Можно конечно выполнить команду mvn install, но это сильно скажется на быстродействии и это лишнее действие для пользователя, о котором он должен помнить. Т.е. на данный момент этот механизм дефолтного IDEA Maven плагина по моему мнению не очень подходит для работы. Но справедливости ради надо заметить, что работа в этом направлении у них идет, судя по коммитам в GithHub, но пока еще не готово. И я очень жалею что не выкатил свой механизм запуска тестов раньше, технически у меня для этого в плагине все было готово уже очень давно.
Есть еще такой очень популярный плагин как Maven Helper. На Habr про него можно почитать в статье, где он упоминается. Этот плагин приобрел широкую известность благодаря реализации Dependency Analyzer как в Eclipse IDE. Данный плагин увидел свет в 2014 году, в то время как данная фича в дефолтном IDEA Maven плагине появилась лишь в 2022 году… Но помимо этого он также предоставляет ряд полезных действий, одно из которых это как раз запуск тестов через делегирование их выполнения Maven Surefire Plugin. Данный action был добавлен в 2020 году. Посмотрим что получилось. Запускаем тот же тест и…

Видим ту же самую ошибку. Т.е. решение также очень сырое, хотя ход мыслей правильный. Чтобы это заработало, нужно запустить тест через родительский pom файл, через ключ -pl указать модуль где находится нужный тест, через ключ -am сказать мавену что нужно также собрать все зависимые модули, чтобы избежать той ошибки, которая воспроизводится на предыдущих двух плагинах, и через опцию -Dsurefire.failIfNoSpecifiedTests=false плагина Surefire, сообщить ему что не надо падать, если указанный тест не найден в первом же модуле, т.к. он начинает его поиск с рутового проекта, откуда происходит запуск.
Вот так по итогу будет выглядеть правильный запуск теста через Maven:
mvn test -pl :zipkin-junit5 -am -Dtest=<testName> -Dsurefire.failIfNoSpecifiedTests=false
Посмотрим что получилось:

Тест успешно выполнился. Для запуска теста использовался Maven Daemon что позволяет существенно сократить время выполнения теста. Как видно из примера, данный тест зависит от шести модулей, и благодаря переиспользованию Maven контекста, каждый последующий запуск теста занимает менее 1.5 секунд. Maven Daemon и путь к нему можно установить в настройках Easy Maven плагина. А если использовать еще и Maven Build Cache, который доступен начиная с версии 3.9.x, то мы не будем уступать ни Gradle ни встроенному в IDEA процессу запуска Jvm приложений по скорости.
Помимо этого, тесты можно не просто запускать, но и отлаживать при помощи Remote Debug, для этого в консоли достаточно кликнуть по номеру порта для отладки:

Запуск тестов в Easy Maven происходит через контекстное меню на имени метода или имени класса. Я решил не переопределять стандартные действия на боковой панели, чтобы у пользователя была возможность использовать оба способа.
Запуск приложений
Запуск приложений будем проверять, на небольшом Spring проекте из двух модулей: web и core, где web зависит от core.
С включенной опцией “Delegate IDE build/run actions to Maven” дефолтный IDEA Maven plugin запускает приложение с помощью maven exec plugin, выполняя goal exec. Запуск проходит без ошибок, но… происходит install, что опять бьет по перфомансу, учитывая что дефолтный IDEA Maven plugin получил интеграцию с Maven Daemon только в последнем релизе в отличии от моего плагина, где она доступна практически с самого начала. Т.к. Easy Maven без разницы как будет запущен Maven проецесс: mwn, mwnw, mwnd. Помимо того что выполняется install, также выполняются все тесты, если их не отключить руками в настройках. Что делает применение данного способа затруднительным практически для любого проекта. Install делается для того чтобы избежать все той же пресловутой ошибки что модуль core не найден, как при запуске тестов.

С maven exec plugin действительно есть проблема, что для многомодульных проектов его невозможно заставить работать, не выполнив предварительно install, и никакие дополнительные Maven параметры не помогают. Или может быть я так и не научился его готовить? Если кто знает ответ, то прошу поделиться в комментариях.
Но можно поступить по другому: выполнить фазу package, с выключенными тестами. С применением Maven Daemon и/или Maven Build Cache, это займет примерно столько же времени как и инкрементальная компиляция IDEA. А далее можно запустить полученный jar артефакт с помощью готовых actions IDEA. В случае мульти-модульного проекта в Easy Maven будут также использованы ключи -pl & -am при сборке чтобы использовать только необходимые для запуска jar файла модули:

Но для Spring Boot проектов есть соответствующий Maven плагин. Выполнив его goal: spring-boot:run, мы можем делегировать запуск приложения Maven. Мой плагин детектирует такой случай - что запускается main метод Spring Boot проекта и выполняет действие описанное выше. Запускается только необходимый минимум, без всяких тестов, что экономит время пользователя и ему не надо об этом думать.

Как показано выше, в случае отладки подключается Remote Debug и нужно кликнуть в консоли на соответствующую ссылку чтобы подключить отладчик.
Для Quarkus проектов, аналогичная история, он по умолчанию имеет богатый “тулинг” для работы с билд тулами. Чтобы запустить приложение для отладки достаточно выполнить quarkus-dev из тул окна Easy Maven:

Как видно популярные фреймворки имеют свои плагины для билд систем и с ними не возникает вообще никаких проблем. А для всех остальных случаев, можно выполнять фазу package и далее запускать и отлаживать готовый jar файл средствами IDEA как это было показано выше.
Заключение
В данной статье я постарался сделать так чтобы отладка, запуск и тестирование Maven приложений происходило максимально нативным способом, как это обычно и происходит на пайплайнах CI/CD. И свести к минимуму рутинную работу по импорту настроек компилятора в IDEA т.к. это потенциально узкое место, где можно ошибиться.
Этой статьей я заканчиваю серию публикаций о Easy Maven. Так как базовые операции - импорт проекта, а также его запуск и тестирование, полностью делегировано Maven. Далее по мере сил и возможностей буду заниматься поддержкой и небольшими доработками/улучшениями. Если у вас есть какие то пожелания по поводу того, что вам чего либо не хватает, можете написать в комментарии или завести issue.
Буду рад, если это будет кому то полезно и если вы найдете время и попробуете мой плагин и дадите какую либо обратную связь или сообщите об ошибках. Может быть у вас также есть проблемы с импортом проекта или запуском тестов в IDEA? Тогда не стесняйтесь писать об это в комментариях или в лс. Постараюсь помочь решить ваши проблемы. Проект можно скачать на marketplace или с GitHub.