Введение в Gradle - систему для автоматизации сборки приложений. Часть 1.
t.me/Golang_googleGradle — система для автоматизации сборки приложений и сбора статистики об использовании программных библиотек, применяющая языки Groovy, Java, JavaScript, Kotlin и т. д., а также решения из фреймворков Apache Ant и Apache Maven.
плагины на JavaScript, C++, Swift, Scala. Система распространяется как программное обеспечение с открытым исходным кодом по лицензии Apache License 2.0.
Назначение Gradle
Ручная сборка приложения для запуска на устройстве требует много времени и ресурсов. Она затягивает процесс разработки и релиза.
Чтобы ускорить его, программисты создают скрипты, автоматизирующие выполнение типовых задач. Это сокращает время сборки, но усложняет работу над командным проектом другим разработчикам.
Проблему решили системы автоматической сборки приложений. Первая — Ant — появилась в 2000 году. В 2004 году вышла Maven. Для описания сценариев сборки системы использовали язык разметки XML. Его недостаток — неконтролируемое разрастание при попытках собрать крупный многомодульный проект.
В 2006 году появилась первая версия Gradle. Она позволила решить основные проблемы:
- реализацию больших многомодульных сборок путем последовательного и параллельного выполнения основных и добавочных модулей;
- ускорение сборки за счет кеширования компонентов через общую сеть с использованием Gradle Build Cache;
- управление зависимостями, то есть подключаемыми к проекту фреймворками, библиотеками и другими компонентами;
- упрощение рабочего процесса за счет автоматизации типовых задач и веб-визуализации сборки.
Gradle использует многие решения, которые применяются в Ant и Maven. Три системы широко интегрированы друг с другом: проект, разработанный для одной из них, можно собрать в другой. Например, основным источником подключаемых внешних компонентов в Gradle является хранилище Maven.
Особенности Gradle
Использование диалекта Groove и Kotlin вместо XML
Оба объектно-ориентированных языка разработаны как дополнения к Java, используют похожий синтаксис, совместимы с теми же библиотеками и другим Java-кодом. Благодаря ему стало проще писать сценарии сборки и сравнительно быстро создавать сложные проекты.
Выполнение задач, основанное на направленных ациклических графах
В них узлы связаны не циклами, а путями, которые могут выходить из начального узла и приходить в конечный пункт различными способами. Ациклические графы оптимизируют внутреннюю объектную модель приложения и управление зависимостями, повышают гибкость сборки.
Код на Gradle проще и меньше. Разница заметна при реализации сборок с большим числом зависимостей.
Декларативный характер сборки
Разработчик просто задает цели, желаемый конечный результат, а система сама подбирает пути его достижения.
Структурирование сборки
Благодаря использованию общих принципов проектирования Gradle позволяет создать удобный, понятный и быстро реализуемый проект.
Проработанный API
Подробный и хорошо продуманный программный интерфейс упрощает отслеживание и настройку конфигурации сборки, контроль ее исполнения.
Универсальность
Система совместима с задачами Ant, инфраструктурой репозитория (сетевого хранилища) Maven и lvy, где можно опубликовать и получить зависимые компоненты. Есть также конвертеры для превращения Maven pom.xml в скрипт Gradle.
Простота миграции
Gradle легко приспосабливается к любой структуре, благодаря чему можно переносить с него и на него проекты, разработанные для других систем сборок.
Открытый код
Система распространяется по свободной лицензии Apache Software License (ASL), поэтому сторонние разработчики смогли написать множество полезных плагинов, библиотек и других компонентов. Они расширяют функционал и создают полноценную Gradle-экосистему.
Gradle Wrapper
Опция разрешает реализацию сборок, созданных в Gradle, на машинах, где система не установлена. Это упрощает непрерывную интеграцию серверов.
Гибкость языка
Groove, в отличие от жестко заданных XML-иерархий Ant и Maven, дает разработчику больше вариантов действия, позволяет оптимизировать проект.
Поддержка каскадной модели
Система сама определяет, какие компоненты дерева разработки были изменены или остались прежними. И, соответственно, какие зависящие от них задачи нужно перезапустить и обновить.
Как работает Gradle
В общем виде Gradle создает текстовый файл сценария сборки (BuildScript), состоящей из следующих компонентов:
- Project (проект). Это конечный результат работы сценария. Проект представляет собой JAR-файл, веб-приложение или zip-файл, включающий Java-архивы, созданные другими проектами. Проект может состоять как из одного модуля (одномодульный проект), так и из нескольких подмодулей (многомодульный проект). В многомодульном проекте каждый подмодуль можно рассматривать как самостоятельный Gradle-проект.
- Task (задачи). Это набор действий с проектом. Задачи могут быть связаны друг с другом. Под сборкой проекта понимается выполнение одной или нескольких связанных задач. Проект считается успешно собранным, когда выполняется задача или набор связанных задач. Как правило, результат сборки – набор артефактов, дистрибутивов, их размещение в репозитории, установка и запуск на другом компьютере в Сети.
- Dependency (зависимости). В ходе сборки могут быть использованы зависимости. Они бывают внешними и внутренними. Внешние — библиотеки, созданные разработчиками со всего мира и расположенные в репозиториях (repositories). Внутренние (подмодули в многомодульных проектах) — библиотеки, разработанные внутри текущего проекта и оформленные в виде подмодуля.
Описание проекта находится в файле build.gradle, настройки указываются в файле gradle.settings. Функциональность скрипта build.gradle может быть расширена с помощью служебного подпроекта buildSrc внутри проекта, а также подключаемых модулей — плагинов. Плагины подразделяются на встроенные и сторонние. Сторонние плагины можно найти на официальном сайте.
Как скачать и установить Gradle
Для получения дистрибутива нужно перейти на официальный сайт Gradle на страницу релизов и скачать последнюю версию.
Есть два варианта дистрибутива:
- binary-only — только двоичные файлы, достаточные для работы;
- complete — те же файлы, что и в первом варианте, плюс документация и исходный код.
Для установки достаточно распаковать содержимое zip-архива в любую доступную папку.
Чтобы запустить Gradle, нужно указать в командной строке полный путь до файла gradle (для Linux и MacOS) или gradle.bat (для Windows).
Для более простого использования можно создать переменную окружения GRADLE_HOME, указывающую путь с распакованным дистрибутивом, и добавить папку $GRADLE_HOME/bin/ (для Linux и MacOS) или %GRADLE_HOME%\bin\ (для Windows) к переменной PATH.
борка Java кода
Начнем с простого, создадим очень простой build.gradle
в корневой папке проекта(там, где src), который содержит только одну строчку:
apply plugin: 'java'
Эта единственная строчка в конфигурации сборки приносит значительную пользу. Запустите gradle tasks снова и вы увидите новые задачи в списке, включая задачи для сборки проекта, создания JavaDoc и запуска тестов.
Вы будете изпользовать задачу gradle build достаточно часто. Эта задача компилирует, тестирует и упаковывает код в JAR-файл. Вы можете запустить её таким образом:
gradle build
Через несколько секунд, "BUILD SUCCESSFUL" будет означать, что сборка прошла успешно.
Чтобы увидеть результаты сборки, посмотрите на содержимое каталога build. Здесь вы найдете несколько директорий, среди которых три наиболее значимые:
- classes. Скомпилированные .class файлы
- reports. Отчеты в течении сборки(такие как отчеты о тестировании)
- libs. Библиотеки для сборки проекта(обычно в виде JAR и/или WAR файлов)
Классы в каталоге с .class файлами генерируются во время сборки Java-кода. Соответственно, вы должны найти там HelloWorld.class и Greeter.class.
На данный момент проект не имеет зависимостей от библиотек, поэтому ничего нет в папке dependency_cache.
Каталог отчетов должен содержать отчет о выполнении тестов для проекта. Т.к. проект пока не содержит тестов, данный отчет будет нам неинтересен.
Каталог библиотек должен содержать JAR-файл с названием каталога проекта. В дальнейшем, вы увидите, как указывать имя JAR-файла и его версию.
Объявление зависимостей
Простой "Hello World" пример полностью автономный и не зависит от каких-либо дополнительных библиотек. Однако, большинство приложений зависит от внешних библиотек, с реализацией распостраненного и/или сложного функционала.
К примеру, предположим, что в дополнение к "Hello World!" вы хотите, чтобы приложение печатало текущую дату и время. Вы могли бы использовать функциональность из стандартных(native) Java библиотек, но мы можем сделать это и другими интересными способами, например с помощью Joda Time библиотеки.
Во первых, изменим HelloWorld.java
, как показано ниже:
package hello; import org.joda.time.LocalTime; public class HelloWorld { public static void main(String[] args) { LocalTime currentTime = new LocalTime(); System.out.println("The current local time is: " + currentTime); Greeter greeter = new Greeter(); System.out.println(greeter.sayHello()); } }
Здесь HelloWorld
использует Joda Time LocalTime
класс для получения и печати текущего времени.
Если бы вы запустили gradle build
для сборки проекта сейчас, то получили бы ошибку сборки, потому что вы не объявили Joda Time компилируемую зависимость в сборке.
Во-вторых, вам необходимо добавить источники сторонних библиотек:
repositories { mavenLocal() mavenCentral() }
Блок repositories
означает, что сборка должна разрешать зависимости из Maven Central репозитория. Gradle опирается в основном на многие соглашения и возможности, определенные в инструменте сборки Maven, включая использование Maven Central как источник библиотек зависимостей.
Теперь, когда мы готовы к приему сторонних библиотек, объявим их:
dependencies { compile "joda-time:joda-time:2.2" }
В блоке dependencies
вы описываете единственную зависимость Joda Time. В частности, вы запрашиваете(читаем справа на лево) версию 2.2 библиотеки joda-time в joda-time группе.
Другое, что хотелось бы отметить, это необходимость указания ключевого слова compile
, обозначающее доступность библиотеки во время компиляции(а если бы вы собирали WAR файл, то была бы включена /WEB-INF/libs папка в WAR). Также существуют другие заметные ключевые слова, среди которых:
providedCompile
. Требуемые зависимости для компиляции кода, но которые будут доступны во время работы кода контейнера(например, Java Servlet API)testCompile
. Зависимости, используемые для компиляции и запуска тестов, но не требуемые для компиляции и запуска кода проекта
И наконец, назначим имя для нашего JAR артефакта.
jar { baseName = 'gs-gradle' version = '0.1.0' }
jar
блок определяет, как JAR файл будет назван. В данном случае мы получим gs-gradle-0.1.0.jar
.
Теперь, если мы запустим gradle build
, Gradle должен будет загрузить Joda Time зависимость из репозитория Maven Central и успешно собрать проект.
Это конец первой части, во второй мы начнем собирать проект.
А пока рекомендуем почитать по теме статью на хабре https://habr.com/ru/post/677826/.