Лекция 4

01.01.0001

Лекция 4. Системы сборки

Зачем нужны системы сборки

Технический подход в разработке заключается в том, что программы и библиотеки разбивают на части — пакеты и модули. В сообществе Java популярно написание библиотек на все случаи жизни и выкладывание их в общий доступ.

Дополнительный стимул — Java получила большую популярность на бэкенде. У серверного ПО более высокие требования к надёжности, и использование проверенных временем библиотек предпочтительнее написания своего кода.

Легко встретить бэкенд-проект из нескольких десятков модулей и сотни библиотек. Описывать (и изменять!) сценарии сборки таких проектов вручную — чрезвычайно трудно.

Что такое автоматизация сборки?

Автоматизация сборки — это процесс автоматизации задач, необходимых для создания, выполнения и тестирования программ.

Исторически такие задачи решались с помощью make-файлов. Сегодня — с помощью средств автоматизации сборки или серверов сборки. Термины «автоматизация сборки» и «система сборки» используются как синонимы.

Эволюция инструментов сборки в Java

В начале был Make, потом GNU Make. Сегодня в экосистеме JVM доминируют три инструмента:

  1. Apache Ant + Apache Ivy — «Муравей с плющом»
  2. Apache Maven — «Знаток/Эксперт»
  3. 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>). Типичный набор:

  1. clean — отчистка артефактов предыдущей сборки
  2. compile — запуск javac
  3. jar — упаковка class-файлов в Java Archive
  4. 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 — его жизненный цикл. Пока проект следует определённым стандартам, через него можно легко пройти полный цикл.

ФазаОписание
1validateПроверяет корректность метаинформации о проекте
2compileКомпилирует исходники
3testПрогоняет тесты
4packageУпаковывает классы в артефакт: jar, war, zip
5verifyПроверяет корректность артефакта и соответствие требованиям качества
6installКладёт артефакт в локальный репозиторий
7deployЗаливает артефакт на production-сервер или удалённый репозиторий

Maven-плагины

Жизненный цикл можно расширить с помощью плагинов. Плагины — самая обычная вещь в Maven: чтобы задать нюансы сборки, нужно подключить плагин.

Плагины описываются почти так же, как зависимости:

  • dependenciesplugins
  • dependencyplugin
  • repositoriespluginRepositories

Список популярных 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:

  1. Глобально через gradle, установленный в системе
  2. Через gradlew — Wrapper (обёртка)

Преимущество Wrapper:

  • Версия Gradle одинакова у всей команды
  • Никому не нужно вручную качать дистрибутив
  • Wrapper установит нужную версию инструментов локально для проекта