Blok dependencies di build.gradle.kts adalah bagian yang paling sering berubah sepanjang siklus hidup proyek. Setiap library yang kita tambahkan, baik untuk produksi maupun test, dideklarasikan di sini. Pemilihan configuration yang tepat (implementation vs api vs compileOnly) memengaruhi waktu kompilasi inkremental, ukuran artefak final, dan batas API yang diekspos ke konsumer. Pada chapter ini kita akan membahas setiap configuration, format koordinat dependensi, serta pola deklarasi yang umum.
Configuration di Gradle #
Configuration adalah label yang menentukan kapan sebuah dependensi tersedia di classpath. Lima configuration berikut paling sering dipakai:
| Configuration | Saat compile | Saat runtime | Diekspos ke konsumer |
|---|---|---|---|
implementation | Ya | Ya | Tidak |
api | Ya | Ya | Ya |
compileOnly | Ya | Tidak | Tidak |
runtimeOnly | Tidak | Ya | Tidak |
testImplementation | Hanya test compile | Hanya test runtime | Tidak |
Pilihan configuration memengaruhi rantai dependensi. Misalnya, bila modul A memakai implementation ke modul B, dan B memakai library C, maka A tidak dapat melihat class-class dari C langsung. Sebaliknya, bila A memakai api ke B, A dapat melihat class-class C di signature public B.
Format Koordinat #
Setiap dependensi dideklarasikan dalam format group:name:version:
- group: organisasi/namespace (mis.
org.jetbrains.kotlinx,com.fasterxml.jackson.core) - name: nama artefak (mis.
kotlinx-coroutines-core,jackson-databind) - version: nomor versi (mis.
1.8.1,2.17.0)
Versi bisa berupa angka tetap (1.8.1), range ([1.0,2.0)), atau dynamic version (+, latest.release). Hindari dynamic version di CI karena membuat build tidak reproducible.
Deklarasi Dependensi #
dependencies {
// Produksi: library utama
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3")
// Logging facade (compile) + implementation (runtime)
compileOnly("org.slf4j:slf4j-api:2.0.13")
runtimeOnly("ch.qos.logback:logback-classic:1.5.6")
// HTTP client
implementation("io.ktor:ktor-client-core:2.3.12")
implementation("io.ktor:ktor-client-cio:2.3.12")
// Test
testImplementation("org.junit.jupiter:junit-jupiter:5.10.0")
testImplementation("io.mockk:mockk:1.13.10")
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.1")
}Mari kita bedah contoh di atas:
kotlinx-coroutines-coresebagaiimplementation: library ini dipakai internal modul; tidak perlu diekspos ke konsumer.slf4j-apisebagaicompileOnly: kita mengkode dengan API SLF4J, tetapi implementasi logback disediakan oleh konsumer modul. Pola ini lazim untuk library.logback-classicsebagairuntimeOnly: hanya dibutuhkan saat runtime; tidak ada class dari logback yang muncul di signature public modul.junit-jupitersebagaitestImplementation: hanya tersedia di source settest; tidak disertakan di JAR produksi.
Demonstrasi Configuration #
Kode berikut mencantumkan daftar configuration utama beserta contoh deklarasi.
fun main() {
println("=== Konfigurasi Dependensi Gradle ===")
println("Empat configuration utama di Gradle:")
println()
println(" implementation - dependensi saat compile + runtime, tidak diekspos ke konsumer")
println(" api - dependensi saat compile + runtime, diekspos ke konsumer")
println(" testImplementation - dependensi hanya untuk src/test saat compile + runtime")
println(" compileOnly - dependensi hanya saat compile, tidak di-runtime")
println(" runtimeOnly - dependensi hanya saat runtime, tidak saat compile")
println(" annotationProcessor / ksp - pemroses anotasi (KAPT/KSP)")
println()
println("Contoh deklarasi:")
println(" implementation(\"org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1\")")
println(" testImplementation(\"org.junit.jupiter:junit-jupiter:5.10.0\")")
println(" compileOnly(\"org.slf4j:slf4j-api:2.0.13\")")
println(" runtimeOnly(\"ch.qos.logback:logback-classic:1.5.6\")")
println()
println("Format koordinat: group:name:version")
println(" group : organisasi (mis. org.jetbrains.kotlinx)")
println(" name : artefak (mis. kotlinx-coroutines-core)")
println(" version : versi (mis. 1.8.1)")
}Output yang Dihasilkan:
=== Konfigurasi Dependensi Gradle ===
Empat configuration utama di Gradle:
implementation - dependensi saat compile + runtime, tidak diekspos ke konsumer
api - dependensi saat compile + runtime, diekspos ke konsumer
testImplementation - dependensi hanya untuk src/test saat compile + runtime
compileOnly - dependensi hanya saat compile, tidak di-runtime
runtimeOnly - dependensi hanya saat runtime, tidak saat compile
annotationProcessor / ksp - pemroses anotasi (KAPT/KSP)
Contoh deklarasi:
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1")
testImplementation("org.junit.jupiter:junit-jupiter:5.10.0")
compileOnly("org.slf4j:slf4j-api:2.0.13")
runtimeOnly("ch.qos.logback:logback-classic:1.5.6")
Format koordinat: group:name:version
group : organisasi (mis. org.jetbrains.kotlinx)
name : artefak (mis. kotlinx-coroutines-core)
version : versi (mis. 1.8.1)Mari kita telaah kode di atas:
- Daftar configuration: tabel ringkas yang menunjukkan kapan setiap configuration relevan. Pembaca dapat memakainya sebagai panduan cepat saat menulis
dependenciesblock baru. - Contoh koordinat: menampilkan string lengkap
group:name:version. Format ini adalah notasi string yang dipakai Gradle; notasi alternatif berbasis map (group = "...", name = "...", version = "...") juga valid tetapi lebih panjang. - Catatan
annotationProcessor/ksp: configuration khusus untuk pemroses anotasi. KAPT menambahkapt, KSP menambahksp.
Tipe Configuration Khusus #
Beberapa configuration tambahan muncul sesuai plugin yang aktif:
plugins {
kotlin("jvm")
id("com.google.devtools.ksp") // menambah ksp()
kotlin("kapt") // menambah kapt()
}
dependencies {
// KSP: pemroses anotasi native Kotlin
ksp("dev.zacsweels.autodapter:autodapter-ksp:1.0.0")
// KAPT: pemroses anotasi javac lama
kapt("com.google.dagger:dagger-compiler:2.51.1")
// Multiplatform: source set khusus
// commonMain implementation(), jvmMain implementation(), dll.
}Best Practices #
Beberapa pedoman praktis:
- Default ke
implementation. Naikkan keapihanya bila tipe dependensi muncul di signature public modul. - Untuk logging:
compileOnlyAPI facade +runtimeOnlyimplementation. Hindari binding langsung ke Logback/Log4j. - Untuk library yang dipakai hanya di test: selalu
testImplementation, janganimplementation. - Untuk versi: pakai version catalog (chapter terpisah) untuk memusatkan dan menghindari duplikasi.
Referensi Lanjutan #
- Gradle
— panduan resmi Kotlin + Gradle untuk deklarasi dependensi
implementationdanapi - Gradle User Guide — buku panduan Gradle yang merinci konfigurasi dependensi dan resolusi versi
Penutup #
Pemilihan configuration yang tepat adalah keputusan arsitektur: memengaruhi build time, binary size, dan batas API. Pada chapter berikutnya kita akan membahas task Gradle secara umum — termasuk task bawaan yang ditambahkan plugin Kotlin dan cara menulis task custom.