Почему Gradle кричит "Deprecated features" и что с этим делать?
Вы когда-нибудь запускали сборку Kotlin-проекта и видели пугающее сообщение: Deprecated Gradle features were used in this build, making it incompatible with Gradle 5.0? Если да — вы не одиноки. Этот вопрос собрал тысячи просмотров на Stack Overflow, и сегодня мы разберем его вдоль и поперек.
Представьте: вы пишете на Kotlin, все работает, но Gradle вдруг начинает капризничать. Он говорит: "Эй, ты используешь старые фишки, которые я уберу в версии 5.0!". Это похоже на то, как если бы ваш любимый кофе-автомат сообщил, что завтра он перестанет принимать старые чашки. Неприятно, но решаемо.
В этой статье мы не просто покажем, как убрать ошибку. Мы сравним три подхода к решению: от быстрого "заплаточного" до профессионального рефакторинга. Вы узнаете, почему Gradle считает ваш код устаревшим, и как переписать его на современный лад.
Что такое deprecated features в Gradle?
Deprecated (устаревшие) функции — это те части API, которые разработчики Gradle планируют удалить в будущем. Они оставлены для обратной совместимости, но использовать их больше не рекомендуется. Когда вы видите это предупреждение, Gradle буквально говорит: "Твой проект соберется сейчас, но после обновления до версии 5.0 — нет".
Чаще всего проблема кроется в:
- Устаревших плагинах (например, старые версии
kotlin-gradle-plugin) - Неявных зависимостях (использование
compileвместоimplementation) - Скриптах на Groovy, которые не адаптированы под Kotlin DSL
- Прямых вызовах deprecated методов в
build.gradle
Подход 1: Быстрое решение — подавление предупреждений
Самый простой (но не самый правильный) путь — просто сказать Gradle: "Заткнись и работай". Это как заклеить лампочку Check Engine скотчем. Машина поедет, но проблемы останутся.
Добавьте в build.gradle.kts (Kotlin DSL) следующий блок:
tasks.withType<Wrapper> {
gradleVersion = "4.10.3" // заморозка версии
}
// Или подавление предупреждения
allprojects {
tasks.withType<AbstractCompile> {
options.isDeprecation = false
}
}
Плюсы: быстро, не требует изменений кода, сборка проходит.
Минусы: вы не решаете проблему, а лишь откладываете. При переходе на Gradle 5.0+ проект сломается. Кроме того, вы пропускаете важные улучшения производительности и безопасности.
Когда использовать: только если вам нужно срочно собрать проект, а времени на рефакторинг нет. Но обязательно запланируйте нормальное решение.
Подход 2: Миграция на современные конфигурации
Это "золотая середина". Вы не просто затыкаете ошибку, а приводите проект в порядок. Давайте разберем типичные проблемы на примере Kotlin-проекта.
Замена compile на implementation/api
Старый способ объявления зависимостей — compile — был deprecated еще в Gradle 3.0. Вместо него используйте implementation и api.
Было (Groovy):
dependencies {
compile 'org.jetbrains.kotlin:kotlin-stdlib:1.3.72'
compile 'com.squareup.retrofit2:retrofit:2.9.0'
}
Стало (Kotlin DSL):
dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.9.0")
implementation("com.squareup.retrofit2:retrofit:2.9.0")
}
Разница простая: implementation скрывает зависимость от потребителей модуля, ускоряя сборку. api — делает её видимой, как старый compile.
Обновление плагина Kotlin
Старые версии kotlin-gradle-plugin часто используют deprecated API Gradle. Проверьте актуальную версию на kotlinlang.org и обновите:
plugins {
kotlin("jvm") version "1.9.0" // было 1.3.x
id("org.jetbrains.kotlin.plugin.spring") version "1.9.0"
}
Переход на Kotlin DSL (build.gradle.kts)
Если ваш проект всё ещё использует Groovy (build.gradle), конвертируйте его в Kotlin DSL. Это не только модно, но и позволяет избежать многих deprecated конструкций, так как Kotlin DSL строже типизирован.
Пример конвертации:
// Было (Groovy):
android {
compileSdkVersion 28
defaultConfig {
minSdkVersion 21
targetSdkVersion 28
}
}
// Стало (Kotlin DSL):
android {
compileSdk = 34
defaultConfig {
minSdk = 21
targetSdk = 34
}
}
Плюсы: вы устраняете причину предупреждения, проект готов к Gradle 5.0+, улучшается читаемость и поддержка.
Минусы: требует времени на рефакторинг, возможны несовместимости с некоторыми плагинами.
Подход 3: Полный аудит и проактивное обновление
Это для перфекционистов. Вы не просто исправляете ошибку, а переписываете систему сборки так, чтобы она была готова к любым будущим изменениям.
Использование Gradle Build Scan
Запустите сборку с флагом --scan и получите детальный отчет о всех deprecated вызовах:
./gradlew build --scan
Вы увидите не только предупреждение, но и точное место в коде, где используется устаревший API. Например, какой плагин или таск вызывает проблему.
Обновление всех плагинов и зависимостей
Создайте файл gradle.properties и укажите версию Gradle, к которой стремитесь:
gradle.wrapper.version=8.5
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
Затем обновите wrapper:
./gradlew wrapper --gradle-version 8.5
После этого пройдитесь по всем плагинам: Android Gradle Plugin, Kotlin, Detekt, Ktlint и т.д. Каждый из них мог использовать deprecated фичи.
Переход на Version Catalogs (libs.versions.toml)
Это современный способ управления зависимостями, который Gradle активно продвигает. Создайте файл gradle/libs.versions.toml:
Блоги
Рекомендаций по книгам
Читайте также
gRPC в C++: мощный инструмент для микросервисов и не только
Паттерны проектирования в Kotlin: продвинутые техники с примерами
Паттерны проектирования в Java с примерами: полное руководство
Управление памятью в Swift: как работает ARC и сборщик мусора
Логирование в Rust: лучшие практики для начинающих