Лекция 4. Системы сборки
Зачем нужны системы сборки
Технический подход в разработке заключается в том, что программы и библиотеки разбивают на части — пакеты и модули. В сообществе Java популярно написание библиотек на все случаи жизни и выкладывание их в общий доступ.
Дополнительный стимул — Java получила большую популярность на бэкенде. У серверного ПО более высокие требования к надёжности, и использование проверенных временем библиотек предпочтительнее написания своего кода.
Легко встретить бэкенд-проект из нескольких десятков модулей и сотни библиотек. Описывать (и изменять!) сценарии сборки таких проектов вручную — чрезвычайно трудно.
Что такое автоматизация сборки?
Автоматизация сборки — это процесс автоматизации задач, необходимых для создания, выполнения и тестирования программ.
Исторически такие задачи решались с помощью make-файлов. Сегодня — с помощью средств автоматизации сборки или серверов сборки. Термины «автоматизация сборки» и «система сборки» используются как синонимы.
Эволюция инструментов сборки в Java
В начале был Make, потом GNU Make. Сегодня в экосистеме JVM доминируют три инструмента:
- Apache Ant + Apache Ivy — «Муравей с плющом»
- Apache Maven — «Знаток/Эксперт»
- Google Gradle — «Доктор Грейдл»
Apache Ant + Ivy
Ant
Ant был выпущен в 2000 году и быстро стал популярным. Имеет низкую кривую обучения, основан на процедурном программировании.
Недостатки:
- XML как формат скриптов сборки — иерархический по природе, плохо подходит для процедурного подхода
- XML становится неуправляемо большим во всех проектах, кроме очень маленьких
- Изначально не имел управления зависимостями — позже принял Apache Ivy
Ivy
Apache Ivy — менеджер зависимостей для Java-проектов с поддержкой транзитивных зависимостей (возможность использовать зависимости других зависимостей).
Для работы Ivy нужны метаданные о ваших модулях — обычно их определяют в Ivy-файлах. Артефакты зависимостей (.jar) ищутся в настраиваемых репозиториях.
Пример конфигурации Ant с Ivy
<ivy-module version="2.0">
<info organisation="org.apache" module="hello-ivy"/>
<dependencies>
<dependency org="commons-lang" name="commons-lang" rev="2.0"/>
<dependency org="commons-cli" name="commons-cli" rev="1.0"/>
</dependencies>
</ivy-module>
Структура Ant build.xml
В Ant фазы сборки называются целями (<target>). Типичный набор:
- clean — отчистка артефактов предыдущей сборки
- compile — запуск
javac - jar — упаковка class-файлов в Java Archive
- run — запуск архива в JVM
Apache Maven
Maven выпущен в 2004 году как усовершенствование Ant. Это инструмент сборки и менеджер проектов на основе XML.
Ключевое отличие от Ivy: Apache Maven — это не только менеджер зависимостей, но и инструмент управления проектом и его сборкой. Ivy же — только инструмент управления зависимостями.
Maven Central
Репозиторий по умолчанию — Maven Central. Де-факто репозиторий для всех Java-библиотек (аналог nuget.org из мира .NET).
POM — объектная модель проекта
Проекты Maven описываются файлами POM (Project Object Model) — pom.xml. До Maven у каждой IDE был свой формат project-файла (зачастую бинарный). Maven предложил универсальный открытый стандарт.
В pom.xml хранятся:
- Информация о версии стандарта Maven-проекта
- Информация о самом проекте
- Информация об используемых библиотеках (зависимостях)
Структура pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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">
...
</project>
Артефакт в Maven
В стандарте Maven всё (программа, проект, модуль, библиотека) называется артефактом. Артефакт описывается тремя параметрами:
- groupId — пакет, к которому принадлежит приложение, обычно с именем домена
- artifactId — уникальный строковый ключ (id проекта)
- version — версия проекта
Эти три параметра однозначно описывают любой артефакт. Например: org.junit.jupiter:junit-jupiter-api:5.9.2.
Зависимости
Зависимость в терминологии Maven — это какой-либо артефакт, который необходим проекту для корректной работы. Артефактом может быть обычный Java-проект, собранный и распространённый с помощью Maven.
Архетипы
Архетипы — стандартизированные шаблоны проектов. Стартовая структура папок (src, java, test и т.д.) задаётся архетипом. Список архетипов можно получить командой:
mvn archetype:generate
Жизненный цикл Maven
Основное преимущество Maven — его жизненный цикл. Пока проект следует определённым стандартам, через него можно легко пройти полный цикл.
| № | Фаза | Описание |
|---|---|---|
| 1 | validate | Проверяет корректность метаинформации о проекте |
| 2 | compile | Компилирует исходники |
| 3 | test | Прогоняет тесты |
| 4 | package | Упаковывает классы в артефакт: jar, war, zip |
| 5 | verify | Проверяет корректность артефакта и соответствие требованиям качества |
| 6 | install | Кладёт артефакт в локальный репозиторий |
| 7 | deploy | Заливает артефакт на production-сервер или удалённый репозиторий |
Maven-плагины
Жизненный цикл можно расширить с помощью плагинов. Плагины — самая обычная вещь в Maven: чтобы задать нюансы сборки, нужно подключить плагин.
Плагины описываются почти так же, как зависимости:
dependencies→pluginsdependency→pluginrepositories→pluginRepositories
Список популярных Maven-плагинов
| Плагин | Назначение |
|---|---|
maven-compiler-plugin | Управляет Java-компиляцией |
maven-resources-plugin | Управляет включением ресурсов в сборку |
maven-source-plugin | Управляет включением исходного кода |
maven-dependency-plugin | Управляет копированием библиотек зависимостей |
maven-jar-plugin | Создание итогового jar-файла |
maven-war-plugin | Создание итогового war-файла |
maven-surefire-plugin | Управляет запуском тестов |
buildnumber-maven-plugin | Генерирует номер сборки |
Gradle
Gradle выпущен в 2008 году как преемник Maven. Главное отличие — вместо XML использует DSL (Domain Specific Language) на основе Groovy (один из языков JVM).
Преимущества Gradle
- Скрипты сборки намного короче и понятнее, чем Ant/Maven
- Меньше boilerplate-кода
- DSL предназначен для решения конкретной задачи — продвижение ПО через жизненный цикл
Gradle и репозитории
Gradle не имеет собственных репозиториев — использует Maven и Ivy репозитории как источники зависимостей. Интерфейс работы с ними на базовом уровне одинаков.
gradlew — Gradle Wrapper
Существует два варианта работы с Gradle:
- Глобально через
gradle, установленный в системе - Через
gradlew— Wrapper (обёртка)
Преимущество Wrapper:
- Версия Gradle одинакова у всей команды
- Никому не нужно вручную качать дистрибутив
- Wrapper установит нужную версию инструментов локально для проекта