Gradle Kotlin DSL: Полное руководство по конфигурации сборки на Kotlin
1. Что это и зачем нужна?
Gradle Kotlin DSL (Domain Specific Language) — это современный, типобезопасный способ написания сценариев сборки для Gradle, использующий язык программирования Kotlin вместо традиционного Groovy. Вместо файлов build.gradle вы работаете с файлами build.gradle.kts, которые являются полноценными Kotlin-скриптами. Это означает, что вы получаете все преимущества статической типизации: автодополнение в IDE (IntelliJ IDEA, Android Studio), проверку типов на этапе компиляции, рефакторинг и навигацию по коду, что значительно снижает количество ошибок в конфигурации.
Зачем это нужно? Традиционный Groovy DSL, хотя и гибок, часто приводит к "магическим" строкам и ошибкам, которые обнаруживаются только во время выполнения. Kotlin DSL решает эту проблему, делая конфигурацию сборки такой же надежной, как и сам код приложения. Вы можете использовать все возможности Kotlin: лямбды, extension-функции, делегированные свойства, корутины (для выполнения задач) и многое другое. Это особенно ценно в крупных проектах с сотнями модулей, где сложность конфигурации растет экспоненциально.
Основное применение — это настройка сборки JVM-проектов: от простых консольных приложений до многомодульных Android-приложений и серверных проектов на Spring Boot. Kotlin DSL полностью совместим с существующими плагинами и задачами Gradle, но требует явного импорта и использования типов. Это делает процесс сборки более предсказуемым и документируемым. Если вы пишете на Kotlin, использование Kotlin DSL — это естественный выбор, который делает ваш файл сборки частью кодовой базы, а не "инородным телом".
2. Установка
Gradle Kotlin DSL не требует отдельной установки через пакетный менеджер (pip, npm). Он является частью дистрибутива Gradle, начиная с версии 5.0. Вам нужно лишь установить сам Gradle.
Способ 1: Установка через SDKMAN (рекомендуется для Linux/Mac/WSL)
# Установка SDKMAN
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"
# Установка последней версии Gradle
sdk install gradle
# Проверка установки
gradle --version
Способ 2: Установка через Homebrew (macOS)
brew install gradle
Способ 3: Установка через Chocolatey (Windows)
choco install gradle
Способ 4: Ручная установка
Скачайте бинарный дистрибутив с официального сайта, распакуйте его и добавьте папку bin в переменную окружения PATH.
После установки Gradle, для создания проекта с Kotlin DSL, просто используйте команду gradle init и выберите тип скрипта "Kotlin" при настройке.
3. Быстрый старт
Создайте файл build.gradle.kts в корне вашего проекта. Это минимальный пример для Kotlin-приложения с использованием JVM.
// build.gradle.kts
plugins {
kotlin("jvm") version "1.9.22" // Версия Kotlin
application // Плагин для запуска приложения
}
repositories {
mavenCentral()
}
dependencies {
implementation(kotlin("stdlib")) // Стандартная библиотека Kotlin
// Тестовая зависимость
testImplementation(kotlin("test"))
}
application {
mainClass.set("MainKt") // Указываем главный класс
}
Создайте файл src/main/kotlin/Main.kt:
// src/main/kotlin/Main.kt
fun main() {
println("Hello, Gradle Kotlin DSL!")
}
Теперь выполните команду в терминале:
gradle run
Вы увидите вывод: Hello, Gradle Kotlin DSL!. Это ваш первый рабочий проект на Kotlin DSL.
4. Основные методы, функции и классы
Ниже приведены ключевые элементы Kotlin DSL, которые вы будете использовать ежедневно.
4.1. plugins { }
Сигнатура: fun PluginDependenciesSpec.plugin(id: String): PluginDependencySpec (или через extension-функции, например kotlin("jvm"))
Что делает: Блок объявления плагинов. Плагины расширяют функциональность Gradle (например, добавляют задачи для компиляции Kotlin, создания JAR-файлов, запуска тестов). Kotlin DSL предоставляет типобезопасные аксессоры для популярных плагинов.
plugins {
// Типобезопасный способ (рекомендуется)
kotlin("jvm") version "1.9.22"
id("org.springframework.boot") version "3.2.0" // Классический способ через ID
java // Встроенный плагин Java
}
4.2. repositories { }
Сигнатура: fun RepositoryHandler.mavenCentral(): Unit, fun RepositoryHandler.mavenLocal(): Unit, fun RepositoryHandler.google(): Unit
Что делает: Определяет репозитории, из которых Gradle будет скачивать зависимости (библиотеки). Обычно используются Maven Central, Google Maven (для Android) или локальный репозиторий.
repositories {
mavenCentral()
mavenLocal()
// Для Android проектов
google()
// Кастомный репозиторий
maven { url = uri("https://jitpack.io") }
}
4.3. dependencies { }
Сигнатура: fun DependencyHandler.implementation(dependencyNotation: Any): Dependency?, fun DependencyHandler.testImplementation(dependencyNotation: Any): Dependency?, fun DependencyHandler.compileOnly(dependencyNotation: Any): Dependency?
Что делает: Объявляет зависимости проекта. Каждая конфигурация (implementation, testImplementation, compileOnly) определяет область видимости зависимости. Kotlin DSL позволяет использовать строковые нотации или типобезопасные аксессоры.
dependencies {
// Строковая нотация
implementation("com.google.code.gson:gson:2.10.1")
// Типобезопасный способ для Kotlin
implementation(kotlin("stdlib"))
implementation(kotlin("reflect"))
// Для тестов
testImplementation("org.junit.jupiter:junit-jupiter:5.10.0")
// Только во время компиляции
compileOnly("org.jetbrains:annotations:24.0.0")
}
4.4. java { }
Сигнатура: fun JavaPluginExtension.targetCompatibility(version: JavaVersion): Unit, fun JavaPluginExtension.sourceCompatibility(version: JavaVersion): Unit
Что делает: Конфигурирует Java-плагин. Позволяет задать версию исходного кода (sourceCompatibility) и целевую версию JVM (targetCompatibility). Это гарантирует, что ваш код будет совместим с указанной версией Java.
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
// Также можно задать модули (Java 9+)
modularity.inferModulePath.set(true)
}
4.5. kotlin { }
Сигнатура: fun KotlinJvmProjectExtension.compilerOptions { }, fun KotlinJvmProjectExtension.sourceSets { }
Что делает: Блок конфигурации Kotlin-плагина. Позволяет настраивать опции компилятора (например, включение строгих проверок nullability), управлять исходными наборами (source sets) и настраивать многоплатформенные проекты.
kotlin {
// Настройка опций компилятора
compilerOptions {
freeCompilerArgs.add("-Xjsr305=strict") // Строгий режим для аннотаций JSR-305
jvmTarget.set(JvmTarget.JVM_17)
}
// Для многоплатформенных проектов
// jvm()
// js()
}
4.6. tasks { }
Сигнатура: fun TaskContainer.named(name: String, configureAction: T.() -> Unit): TaskProvider, fun TaskContainer.register(name: String, type: KClass, configureAction: T.() -> Unit): TaskProvider
Что делает: Позволяет настраивать существующие задачи (например, test, jar) или создавать новые. Это основной способ кастомизации процесса сборки. Kotlin DSL обеспечивает типобезопасный доступ к задачам.
tasks {
// Настройка существующей задачи test
test {
useJUnitPlatform() // Использовать JUnit 5
testLogging {
events("passed", "skipped", "failed")
}
}
// Создание новой задачи
register("hello") {
doLast {
println("Hello from custom task!")
}
}
}
4.7. val myVersion by extra { } (Extra свойства)
Сигнатура: fun ExtensionAware.extra: ExtraPropertiesExtension
Что делает: Позволяет объявлять пользовательские свойства (extra properties), которые можно переиспользовать в разных частях скрипта. Это помогает избежать дублирования версий и других констант. Используется делегированное свойство by extra.
// Объявление версий
val kotlinVersion by extra("1.9.22")
val coroutinesVersion by extra("1.7.3")
dependencies {
implementation(kotlin("stdlib", kotlinVersion))
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion")
}
// Использование в другой задаче
tasks.register("printVersion") {
doLast {
println("Kotlin version: $kotlinVersion")
}
}
4.8. allprojects { } и subprojects { }
Сигнатура: fun Project.allprojects(configureAction: Project.() -> Unit): Unit, fun Project.subprojects(configureAction: Project.() -> Unit): Unit
Что делает: Используются в многомодульных проектах (в корневом build.gradle.kts). allprojects применяет конфигурацию ко всем проектам (включая корневой), а subprojects — только к дочерним модулям. Это позволяет централизованно задавать общие репозитории, плагины или зависимости.
// В корневом build.gradle.kts
allprojects {
repositories {
mavenCentral()
}
}
subprojects {
// Применяем плагин Kotlin ко всем модулям, кроме корневого
apply(plugin = "org.jetbrains.kotlin.jvm")
dependencies {
implementation(kotlin("stdlib"))
}
}
4.9. configurations { }
Сигнатура: fun ConfigurationContainer.named(name: String, configureAction: Configuration.() -> Unit): Unit
Что делает: Позволяет настраивать конфигурации зависимостей. Это продвинутая техника, используемая для разрешения конфликтов версий, исключения транзитивных зависимостей или создания кастомных конфигураций (например, для аннотационных процессоров).
configurations {
// Исключаем старую версию Log4j из всех зависимостей
all {
exclude(group = "log4j", module = "log4j")
}
// Настройка конфигурации для аннотационных процессоров
compileOnly {
extendsFrom(configurations.annotationProcessor.get())
}
}
4.10. sourceSets { }
Сигнатура: fun SourceSetContainer.named(name: String, configureAction: SourceSet.() -> Unit): Unit
Что делает: Управляет исходными наборами (source sets). По умолчанию есть main и test. Вы можете добавить свои (например, integration