Deklarasi dependensi di Maven berbeda dengan Gradle. Maven memakai scope untuk menentukan ketersediaan dependensi di berbagai phase build. Pemilihan scope yang tepat memengaruhi ukuran JAR akhir dan batas dependensi transitif yang ditarik. Pada chapter ini kita akan membahas empat scope utama Maven, cara deklarasi dependensi di pom.xml, serta perintah pemeriksaan dependency:tree dan dependency:analyze.
Empat Scope Utama #
| Scope | Saat compile | Saat test | Saat runtime | Transitif |
|---|---|---|---|---|
compile (default) | Ya | Ya | Ya | Ya, dengan scope compile |
test | Tidak | Ya | Tidak | Ya, untuk scope test |
provided | Ya | Ya | Tidak | Tidak transitif |
runtime | Tidak | Ya | Ya | Ya, dengan scope runtime |
Mari kita bedah kapan memakai masing-masing scope:
compile(default): dependensi yang dipakai di kode produksi dan runtime. Mis.kotlinx-coroutines-core.test: dependensi hanya untuk unit test. Mis.junit-jupiter,mockk. Tidak disertakan di JAR akhir.provided: dependensi yang disediakan oleh environment runtime. Mis.servlet-apidi Tomcat, atauslf4j-apibila kita publikasikan library dan konsumer yang menyediakan implementasi.runtime: dependensi yang hanya dibutuhkan saat runtime, bukan saat compile. Mis. driver JDBC (org.postgresql:postgresql) yang dipakai via interfacejava.sql.Driver.
Deklarasi di pom.xml #
<dependencies>
<!-- Scope compile (default) -->
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-coroutines-core</artifactId>
<version>1.8.1</version>
</dependency>
<!-- Scope provided: API logging di library publik -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.13</version>
<scope>provided</scope>
</dependency>
<!-- Scope runtime: driver JDBC -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.7.3</version>
<scope>runtime</scope>
</dependency>
<!-- Scope test -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
</dependencies>Demonstrasi Dependensi Maven #
Kode berikut mencantumkan empat scope utama dan perintah pemeriksaan.
fun main() {
println("=== Dependensi Maven ===")
println()
println("Empat scope utama:")
println(" compile (default) - tersedia di compile + runtime + transitif")
println(" test - hanya untuk test compile + test runtime")
println(" provided - compile, tapi tidak di runtime (mis. Servlet API)")
println(" runtime - runtime saja, tidak untuk compile (mis. JDBC driver)")
println()
println("Contoh deklarasi di pom.xml:")
println(" <dependency>")
println(" <groupId>org.jetbrains.kotlinx</groupId>")
println(" <artifactId>kotlinx-coroutines-core</artifactId>")
println(" <version>1.8.1</version>")
println(" <scope>compile</scope>")
println(" </dependency>")
println()
println("Perintah pemeriksaan:")
println(" mvn dependency:tree -> pohon lengkap")
println(" mvn dependency:tree -Dscope=runtime -> filter runtime saja")
println(" mvn dependency:analyze -> deteksi unused/undeclared")
println()
println("Repository default: Maven Central (https://repo1.maven.org/maven2/)")
println("Mirror lokal: settings.xml di ~/.m2/ dapat mengarahkan ke Nexus/Artifactory")
}Output yang Dihasilkan:
=== Dependensi Maven ===
Empat scope utama:
compile (default) - tersedia di compile + runtime + transitif
test - hanya untuk test compile + test runtime
provided - compile, tapi tidak di runtime (mis. Servlet API)
runtime - runtime saja, tidak untuk compile (mis. JDBC driver)
Contoh deklarasi di pom.xml:
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-coroutines-core</artifactId>
<version>1.8.1</version>
<scope>compile</scope>
</dependency>
Perintah pemeriksaan:
mvn dependency:tree -> pohon lengkap
mvn dependency:tree -Dscope=runtime -> filter runtime saja
mvn dependency:analyze -> deteksi unused/undeclared
Repository default: Maven Central (https://repo1.maven.org/maven2/)
Mirror lokal: settings.xml di ~/.m2/ dapat mengarahkan ke Nexus/ArtifactoryMari kita telaah kode di atas:
- Empat scope: ditampilkan dalam format cheat sheet. Pembaca dapat membandingkan dengan tabel di atas untuk memilih scope yang tepat saat menulis
pom.xmlbaru. - Contoh deklarasi: format XML lengkap. Maven sangat verbose dibanding Gradle, tetapi struktur ini konsisten untuk semua dependensi.
mvn dependency:tree: perintahdependency:treeadalah bagian darimaven-dependency-pluginyang sudah terpasang default. Output menampilkan pohon dependensi lengkap dengan indentasi.mvn dependency:analyze: perintah ini mendeteksi dependensi yang dideklarasikan tetapi tidak dipakai (unused declared) serta dependensi yang dipakai tetapi tidak dideklarasikan secara eksplisit (used undeclared). Laporan ini sangat berguna untuk membersihkanpom.xml.
Repository Maven Central #
Repository default Maven adalah Maven Central (https://repo1.maven.org/maven2/). Maven mengunduh dependensi ke cache lokal di ~/.m2/repository/. Struktur direktori mengikuti groupId dengan titik diubah ke /. Mis. org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1 disimpan di:
~/.m2/repository/org/jetbrains/kotlinx/kotlinx-coroutines-core/1.8.1/
├── kotlinx-coroutines-core-1.8.1.jar
├── kotlinx-coroutines-core-1.8.1.pom
└── kotlinx-coroutines-core-1.8.1.jar.sha1Repository Custom #
Untuk menambah repository custom (mis. Nexus internal atau JitPack), edit pom.xml:
<repositories>
<repository>
<id>jitpack</id>
<url>https://jitpack.io</url>
</repository>
</repositories>Untuk konfigurasi global (mirror), edit ~/.m2/settings.xml:
<settings>
<mirrors>
<mirror>
<id>nexus-internal</id>
<url>https://nexus.example.com/repository/maven-public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
</settings>dependency:analyze #
Perintah mvn dependency:analyze menghasilkan dua laporan:
- Used undeclared: dependensi yang dipakai di kode tetapi tidak dideklarasikan secara eksplisit di
pom.xml(hanya transitif). Risiko: bila versi dependensi transitif berubah, kode bisa pecah. - Unused declared: dependensi yang dideklarasikan tetapi tidak dipakai. Bisa dihapus untuk membersihkan POM.
$ mvn dependency:analyze
[INFO] Used undeclared dependencies:
org.jetbrains.kotlin:kotlin-stdlib:2.0.21
[INFO] Unused declared dependencies:
com.google.guava:guava:33.0.0-jreReferensi Lanjutan #
- Kotlin with Maven — panduan resmi Kotlin + Maven untuk deklarasi dependensi Kotlin stdlib dan library lain
- Introduction to the POM — panduan resmi Maven untuk deklarasi dependensi, scope, dan transitive dependency
Penutup #
Pemahaman scope Maven dan mekanisme repository adalah kunci untuk menulis pom.xml yang benar. Untuk proyek Kotlin modern, Gradle adalah default, tetapi Maven tetap relevan untuk integrasi dengan organisasi yang sudah memegang ekosistem Maven. Pada chapter berikutnya kita akan membahas build variants — fitur Gradle untuk menghasilkan beberapa build dari satu proyek (debug/release, flavors).