В данной статье разберемся в практических различиях инструментов для сборки Maven и Gradle. Ведь современным разработчикам катастрофически не хватает времени на погружение во все технологии. Иногда нет времени, что бы прочитать несколько сотен страниц документации по каждому инструменту. Например, на первой работе меня постоянно преследовал стресс из-за того, что я не знаю почти все, что касается настройки и запуска проекта. Так получилось, что с проекта уходил последний java-разработчик. Я должен был принять проект и вести его вместе с другим фронтенд-разработчиком. Я потратил кучу времени на локальный запуск проекта. Но когда все получилось, я закрыл много задач по проекту и получил бесценный опыт. В этой статье я попытаюсь резюмировать свой опыт, который поможет разобраться в сборке многомодульных проектов.
Сначала рассмотрим Maven и его неочевидные настройки, а потом перейдем к Gradle. Для меня Maven оказался проще по сравнению с Gradle, потому что все настройки собраны в одном файле pom.xml. В официальной документации говорится "как только вы ознакомитесь с одним проектом Maven, вы поймете, как строятся все проекты Maven". Это действительно так, но есть пару нюансов. Как правило, приходится вести несколько проектов и все проекты будут хранить зависимости в виде jar-файлов в одном репозитории. Это приводит к тому, что зависимости с более высокой версией будут удалять старые jar-файлы. Это приводит к ошибкам во время сборки проекта.
В таких случаях необходимо настроить отдельный локальный репозиторий для каждого проекта. В настройках Intellij Idea есть вкладка "Build, Execution, Deployment"
, далее "Build Tools"
и в ней Maven
. Для каждого отдельного проекта нужно определить расположение репозитория и файла settings.xml, в котором содержаться пользовательские настройки.
Допустим, у вас несколько проектов с условными названиями - project1, project2, etc. В папке .m2 создаем отдельные директории с такими же названиями, создаем внутри создаем еще одну папку repository и файл settings.xml. В моем случае файл settings создал тимлид, но если нужно создать пользовательские настройки с нуля, то проще всего скопировать глобальные настройки Maven в качестве основы и подредактировать, как будет показано ниже.
Глобальные настройки можно найти в папке conf в директории установки Мавен, если он у вас установлен. Если нет, тогда Вы можете скачать бинарный файл с сайта https://maven.apache.org/download.cgi. Итак, копируем файл settings.xml в папку project1 и начинаем его править.
Для начала можно удалить все комментарии для удобочитаемости. Таким образом, первые строки объявляют версию XML и пространство имен:
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
Это магическая магия для тех, кто не знаком с языком XML, которая является стандартным заголовком в xml-файлах. Если не вдаваться в подробности, то внутри заголовка лежат ссылки на другие xml-файлы, в которых перечисляются так называемые "элементы" (именованные переменные), их значение и тип (напр. name="offline" type="xs:boolean"), минимальное и максимальное количество элементов (minOccurs="0" означает, что этот элемент можно не указывать, minOccurs="1" означает, что элемент нужно указать минимум 1 раз) и пр.
Далее внутри тегов <localRepository>
и </localRepository>
нужно указать путь до папки repository (например, C:\Users\username.m2\project1\repository). Сохраняем и закрываем файл settings.xml. Смотрим в папке /.m2
вместо одной директории repository должны лежать отдельные папки на каждый проект.
Далее возвращаемся в IDE, поочередно открываем проекты project1, project2 etc. и указываем путь до репозитория и файла настроек во вкладке Maven ("Build, Execution, Deployment" -> "Build Tools").
После этого, запускаем задачи Maven clean
и install
, либо нажимаем кнопку Reload All Maven Project
в боковой вкладке Maven. Среда разработки закачивает в новый репозиторий все зависимости и плагины. Теперь если зайти в папку .m2/project1/repository, то можно увидеть новые папки с jar-файлами.
Когда вы закончили с настройкой репозитория, можно перейти к настройке микросервисов. В моем случае это был проект с 15 микросервисами и 14 библиотеками, т.е. это были 29 отдельных проектов со своими pom.xml файлами. И даже если вы знакомы с Maven по учебным проектам, то не сразу можно догадаться, как настроить несколько Maven-проектов, что бы они работали вместе и открывались как один проект.
Сначала нужно найти основной проект (в моем случае это был пустой проект с файлами pom.xml и README.md, без без src). Открываем его в среде разработки Idea, раскрываем вкладу Maven и нажимаем кнопку "Add Maven Project".
Далее поочередно добавляем проекты просто выбирая соответствующие файлы pom.xml в каждом отдельном проекте. На этом настройка Maven проекта завершена.
Прим. Также я столкнулся с двумя сложностями - настройкой БД (Postgres, Liquibase) и Spring Cloud (Eureka, настройка Feign-сервисов, Kafka/Zookeeper). Эти этапы я пропущу, потому что их нужно описать в отдельной статье.
Теперь перейдем к Gradle. Когда я получил проект с gradle, то долго не мог понять, кто является главным среди всех этих gradle-файлов, то есть где аналог pom.xml в gradle-проектах. На самом деле все оказалось просто - это файл build.gradle. И что бы понять, как работает gradle, я предлагаю создать два пустых проекта - один Maven-проект и один Gradle-проект, а также выполнить пару команд, что бы получить визуальное представление о работе обоих систем сборки.
Итак, создаем две пустые директории. В первой создадим pom.xml со следующими полями:
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>example</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<java-version>11</java-version>
<maven.compiler.source>${java-version}</maven.compiler.source>
<maven.compiler.target>${java-version}</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Далее заходим в терминал по адресу этой папки и вводим команду mvn clean install
. В директории появилась папка target с jar-файлом проекта. Теперь если открыть проект в Intellij Idea, то во вкладке External Libraries можно увидеть, что подтянулась зависимость - JUnit.
Сделаем такую же операцию с Gradle. Создаем в новой папке файл build.gradle со следующим содержанием:
plugins {
id 'java'
}
repositories {
mavenCentral()
}
dependencies {
testImplementation group: 'junit', name: 'junit', version: '4.13.2'
}
Заходим в терминал по адресу этой папки и вводим команду gradle wrapper
. В директории появилась две папки - .gradle и gradle (в первой хранится кэш проекта, во втором тонкий jar для gradle, который позволяет запускать gradle-команды на машинах, где не установлен Gradle) и два исполняемых файла - gradlew (для unix-систем) и gradlew.bat (для windows). Аналогично предыдущему примеру в IDE можно увидеть, что в External Libraries уже загрузилась зависимость JUnit.
Если у вас все получилось, то эти два шаблона можно использовать для разработки новых проектов, добавляя зависимости Spring Boot.
Еще одна сложность, с которой я столкнулся в в gradle-проекте, заключается в том, что нужно потратить некоторое время на изучение Groovy (я выбрал Groovy, а не Kotlin). С помощью Groovy можно написать задачи (task
), т.е. такой скрипт по сборке проекта. Или можно использовать плагины, которые импортируют в проект готовые задачи. Например, apply plugin 'java'
позволяет использовать такие команды как gradle compileJava, jar, javadoc
etc.
Список плагинов и импортируемых задач можно посмотреть на официальном сайте Gradle. Но если у вас есть действующий проект и вас просто нужно узнать какие задачи можно выполнить, то воспользуйтесь командой gradle tasks
для вывода на экран всех доступных задач с их описанием.
P.S. Переходя с удаленки в офис и обратно, я сталкивался с такой проблемой, что мои записи с готовыми командами и шпаргалками не оказывались под рукой. Есть разные пути решения этой проблемы. Я решил создать Телеграм-канал, на котором я буду публиковать свои заметки и шпаргалки по веб-разработке, а также статьи о реальном практическом опыте на коммерческих проектах.