webprogr.ru Новости

RSS

{{toodo.preview}}

...
{{toodo.name}}

{{toodo.preview}}

далее..

{{toodo.preview}}

{{toodo.name}}

{{toodo.preview}}

смотреть..

toodo.name

{{toodo.preview}}

{{toodo.name}}

{{toodo.preview}}

перейти...

{{toodo.preview}}

...
{{toodo.name}}

{{toodo.preview}}

далее..

{{toodo.preview}}

{{toodo.name}}

{{toodo.preview}}

смотреть..

toodo.name

{{toodo.preview}}

{{toodo.name}}

{{toodo.preview}}

перейти...


Последние новости

Gradle: Файл сборки (build.gradle) – структура

Типичный Groovy-скрипт Gradle (build.gradle) содержит разделы:
plugins: подключение необходимых плагинов, например id 'java', id 'application', id 'org.springframework.boot' version '3.1.4' и т.д.
group и version: задают координаты проекта (группа и версия артефакта). Аналог Maven <groupId> и <version>.
repositories: список репозиториев для зависимостей – обычно mavenCentral(), иногда mavenLocal(), корпоративные Maven-репозитории или Google Maven для Android.
dependencies: объявление зависимостей. Используются конфигурации: implementation, api (для библиотек, если нужно транзитивно экспортировать), testImplementation, runtimeOnly и т.д. Формат указания – 'group:artifact:version'.
application (опционально): настройки приложения, если применён плагин Application. Указывается mainClass (полное имя класса с методом main), чтобы Gradle знал точку входа для gradle run и формирования скриптов запуска.
tasks: определение дополнительных задач или настройка существующих. Можно написать task <name> {...} для новой задачи или настроить существующую через tasks.named('test') { ... } например.
sourceSets (опционально): если структура каталогов нестандартная, через sourceSets настраивают, где искать исходники. По умолчанию Gradle Java plugin уже создает sourceSet main и test с путями как у Maven. Меняют это, если, например, нужно добавить src/integrationTest/java для интеграционных тестов.
allprojects, subprojects (опционально): в многомодульных проектах, секции, позволяющие задать общие настройки для всех подпроектов или конкретных групп. Например, в корневом build.gradle можно написать allprojects { repositories { mavenCentral() } } чтобы для всех модулей использовать Maven Central, вместо дублирования в каждом.
buildscript (реже сейчас): секция для определения зависимостей, необходимых самому скрипту сборки (например, для старых плагинов, которые не через plugins {} подключаются). В современном Gradle обычно не нужен, заменён на plugin DSL.
additional Gradle-specific configs: например, configurations { ... } чтобы создать или модифицировать конфигурацию зависимостей, publishing { ... } для настройки публикации, test { ... } для конфигурации опций тестирования (внутри можно указать JUnit platform, параметры JVM).






Пояснение:

 Рассмотрим структуру Gradle-скрипта более последовательно:
Подключение плагинов: Блок plugins { } – самая первая часть. Здесь объявляют, какие Gradle-плагины нужны этому проекту. Пример: plugins { id 'java' } – подключает Java Plugin, который добавляет все стандартные задачи сборки Java. Можно указывать версию плагина (для внешних плагинов, например Spring Boot: id "org.springframework.boot" version "3.1.4"). До Gradle 5 был другой синтаксис: apply plugin: 'java', но сейчас принят декларативный plugins блок (в Kotlin DSL вообще возможен только он). Плагинов может быть несколько – они могут быть официальными (java, application, jacoco) или внешними из Gradle Plugin Portal/Maven. При подключении Gradle сам скачает необходимые jar плагина, схоже с Maven (в Gradle тоже есть понятие репозитория плагинов, по умолчанию Gradle Plugin Portal; если плагин опубликован в Maven Central, можно подключить через plugins { id "..." version "..." } используя pluginManagement/buildscript).
Группа и версия: В Gradle проекту можно задать group и version прямо в скрипте. Эти свойства определяют координаты при публикации артефакта. Если их не указать, group по умолчанию пустой (или берётся из settings.gradle, где можно задать rootProject.name), version по умолчанию "unspecified". Для библиотек обязательно указывать, для приложений (которые не распространяются) можно и забыть, но лучше заполнить. Аналога <artifactId> нет, так как имя артефакта Gradle берёт из имени проекта (обычно имя папки). Можно при публикации override имя, но чаще всего имя JAR = имя проекта.
Repositories: Здесь указываются источники, откуда Gradle будет скачивать ваши зависимости. Стандартно:
mavenCentral() – хватит для большинства случаев.
google() – Gradle особым образом знает про Google's Maven (для Android и Google библиотек).
mavenLocal() – добавлять опционально, если хотите, чтобы Gradle искал зависимость в локальном Maven репо (~/.m2). Полезно, если вы собрали что-то локально через Maven и хотите, чтобы Gradle-проект это взял.
Пользовательские: maven { url = uri("https://maven.example.com/repo&quot;) } – напр., если есть частный репозиторий.
JCenter сейчас не используют (если встречаете jcenter(), надо убирать, так как репозиторий недоступен).
В Gradle 7+ jcenter() вообще помечен deprecated.
Репозитории объявленные в build.gradle применяются к dependency resolution. Для плагинов – отдельный блок pluginManagement в settings.gradle или buildscript.repositories, но это частный случай.
Dependencies: Синтаксис Gradle для зависимостей отличается от Maven. Maven делит зависимости по <scope>, а Gradle – по конфигурациям. При подключении Java Plugin Gradle создает набор конфигураций:
implementation – основная конфигурация для зависимостей, необходимых для компиляции и исполнения вашего кода. Она не экспортируется на проекты, которые зависят от вашего (если ваш проект – библиотека, те, кто его подключат, не получат ваши implementation зависимости автоматически).
api – это если ваш проект – библиотека и вы хотите, чтобы те, кто зависят от вашей библиотеки, транзитивно получили эту зависимость. (Пример: вы пишете библиотеку, которая внутри использует Guava и возвращает типы Guava из своего API; тогда Guava имеет смысл объявить как api, чтобы пользователь вашей библиотеки тоже имел её в classpath.)
compileOnly – зависимость нужна только для компиляции (например, какой-то аттрибут или аннотация, не требующая присутствия в runtime).
runtimeOnly – наоборот, нужна только во время выполнения (например, JDBC драйвер, если у вас код рассчитан на его наличие только при запуске).
testImplementation, testCompileOnly, testRuntimeOnly, testApi – аналогичные конфигурации, но применяющиеся только к тестовому коду.
(Есть и другие, например annotationProcessor для kapt/аннотаций.)
Большинство зависимостей идут как implementation. В Gradle указывают в одну строку: implementation 'group:artifact:version'. Версии можно выносить в ext переменные или использовать платформы (Gradle поддерживает BOM – implementation platform('org.springframework.boot:spring-boot-dependencies:3.1.4') – после этого можно добавлять зависимости Spring Boot без версий, Gradle возьмет их из BOM; это похожий механизм на Maven BOM).
Можно также указать зависимости на проекты (модули) Gradle: implementation project(':core') – если многомодульный Gradle, говорит, что текущий модуль зависит от модуля "core".
Пример:
dependencies {
implementation 'com.google.guava:guava:32.0.1-jre'
implementation 'org.apache.commons:commons-lang3:3.12.0'
testImplementation 'org.junit.jupiter:junit-jupiter:5.10.0'
}
Это подключит Guava и Apache Commons Lang как зависимости, а JUnit только для тестов.
application: Если проект – это самостоятельное приложение, а не библиотека, часто применяют плагин application. Тогда появляется возможность указать:
application {
mainClass = 'com.example.myapp.Main'
}
Это упакует в JAR манифест с указанием главного класса, и Gradle предоставит возможность gradle run (и ещё сгенерирует скрипты запуска, если собирать дистрибуцию через installDist/distZip tasks).
В Kotlin DSL аналог:
application {
mainClass.set("com.example.myapp.Main")
}
Если у вас Spring Boot, там другой механизм запуска, и mainClass указывается в самом Spring Boot plugin, но суть в том же – указать Gradle-у точку входа.
Tasks: Gradle-скрипт может определять новые задачи:
С помощью упрощённого синтаксиса task myTask { ... } – создаст Task с именем myTask. Внутри можно указать действие doLast { ... } (или doFirst).
С помощью tasks.create или tasks.register – более продвинутые API, часто используются в Kotlin DSL (где нужно указывать тип задачи, если кастомный, и прочие).
Также можно настраивать существующие задачи. Например,
test {
useJUnitPlatform()
testLogging { events "passed", "failed" }
}
Эта конструкция на Groovy находит задачу test (плагин уже её создал) и конфигурирует: включает JUnit 5 платформу и настраивает логгирование прохождения тестов.
В Kotlin DSL это выглядело бы как:
tasks.test {
useJUnitPlatform()
testLogging {
events("passed", "failed")
}
}
В Gradle общая модель: плагин может определить задачу, но мы всегда можем её параметризовать (в Maven, напротив, плагин определяет goal, и мы параметризуем его через XML, что похоже, но Gradle даёт возможность и код вставлять, не только параметры).
Custom tasks могут быть очень сложными: Gradle позволяет писать свои классы задач (на Java/Groovy) и применять их, либо использовать существующий тип (например, Copy, JavaExec, Zip – в Gradle есть типовые tasks).
Например,
task copyDocs(type: Copy) {
from 'src/docs'
into 'build/docs'
}
– определит задачу копирования документов.
Этот уровень деталей зависит от потребностей. Для большинства Java-проектов обычно не нужно писать много своих тасков – всё покрывают плагины. Но если надо – Gradle это упрощает.
sourceSets: В Java-плагине Gradle already defines:
sourceSets {
main {
java.srcDirs = ['src/main/java']
resources.srcDirs = ['src/main/resources']
}
test { ... аналогично ... }
}
Если вы физически храните код не по Maven соглашениям, можно тут подправить. Например, у вас генерируется код в build/generated-src/ – можно добавить его:
sourceSets.main.java.srcDir 'build/generated-src'
Тогда Gradle включит этот каталог тоже в класс-путь для компиляции. Или, скажем, вы хотите иметь интеграционные тесты отдельно: можно завести sourceSets { integrationTest { java.srcDir 'src/it/java'; resources.srcDir 'src/it/resources' } } – а потом зарегистрировать задачи для нового sourceSet (компиляция, запуск тестов). Это уже advanced usage.
В большинстве случаев, если вы соблюдаете стандарт Maven, нет нужды трогать sourceSets. Gradle видит src/main/java – и так компилирует. Но nice to know, что эта возможность есть.
allprojects/subprojects: В многомодульных Gradle-проектах обычно есть корневой build.gradle и отдельные для модулей. Чтобы не дублировать код, Gradle позволяет в корне написать:
allprojects {
repositories { mavenCentral() }
}
Тогда и корневой, и все модули унаследуют это (к моменту выполнения allprojects {} модули уже созданы). Или
subprojects {
apply plugin: 'java'
group = 'com.mycompany'
version = '1.0.0'
}
– применит ко всем подпроектам java-плагин и задаст им одинаковую группу и версию. Это удобно: один раз вписали – во всех модулях актуально. В Kotlin DSL, кстати, allprojects/subprojects тоже доступны, но там часто предпочитают вместо скриптовых конструкций использовать градловские включаемые скрипты или convention plugins – более композиционный подход. Но это детали.
buildscript {}: Этот блок был нужен, когда требовалось подключить зависимости, чтобы сам buildscript мог выполнить что-то. Например, в эпоху Gradle 4 для использования Kotlin в скриптах, прописывали kotlin-stdlib в buildscript classpath. Сейчас же plugin DSL (plugins { id ... }) заменяет большинство таких случаев. Buildscript classpath можно встретить, например, в Android-проектах старых:
buildscript {
repositories { google() }
dependencies {
classpath 'com.android.tools.build:gradle:7.4.2'
}
}
– это подключение Android Gradle Plugin классическим способом. Но с Gradle обновлений можно и его через plugins {} объявлять, используя pluginManagement.
В целом, новый проект на Gradle редко нуждается в buildscript секции, разве что совсем уникальные случаи.
Подводя итог, build.gradle – это гибкий сценарий сборки. Его структура не жёстко регламентирована как POM, но сложилась традиция располагать блоки именно в вышеприведённом порядке: сначала plugins, затем глобальные настройки (group/version), репозитории, затем зависимости, затем специфичные настройки (tasks, publishing, etc). Kotlin DSL скрипты аналогично структурируются.
Лучшей практикой считается выносить очень громоздкие настройки в отдельные.gradle файлы или писать свой плагин, чтобы build.gradle оставался коротким и читабельным. Однако на небольших проектах всё помещается и так. Главное – он читается как программа, а не как декларация, поэтому помните, что порядок выполнения и область видимости здесь играют роль.
Gradle: Стандартная структура проекта

Рейтинг@Mail.ru