Struktur direktori yang konsisten menentukan apakah proyek Kotlin mudah dimengerti oleh developer baru dan alat-alat otomatisasi (IDE, CI, code generator). Gradle mengikuti pola convention over configuration yang dipinjam dari Maven: kode utama di src/main/kotlin, kode test di src/test/kotlin, dan resource masing-masing di src/main/resources dan src/test/resources. Pada chapter ini kita akan membahas struktur standar, file konfigurasi root, serta cara mengelola proyek multi-modul.

Layout Standar #

text
my-app/
├── settings.gradle.kts       # Konfigurasi root, daftar subproyek
├── build.gradle.kts           # Build script root
├── gradle.properties          # Properti global Gradle
├── gradle/
│   ├── wrapper/
│   │   ├── gradle-wrapper.jar
│   │   └── gradle-wrapper.properties
│   └── libs.versions.toml     # Version catalog (sejak Gradle 7.4)
├── gradlew, gradlew.bat       # Wrapper script
└── src/
    ├── main/
    │   ├── kotlin/com/example/App.kt
    │   ├── java/com/example/Helper.java
    │   └── resources/application.conf
    └── test/
        ├── kotlin/com/example/AppTest.kt
        └── resources/application-test.conf

settings.gradle.kts #

File settings.gradle.kts dievaluasi pada initialization phase. File ini menentukan:

  • Nama root project (rootProject.name)
  • Daftar subproyek yang dimasukkan (include)
  • Lokasi plugin (Portal Gradle, Maven Central, atau internal)
kotlin settings.gradle.kts
pluginManagement {
    repositories {
        gradlePluginPortal()
        mavenCentral()
    }
}

dependencyResolutionManagement {
    repositories {
        mavenCentral()
    }
}

rootProject.name = "my-app"

include(":app", ":core", ":web")

build.gradle.kts Root #

Untuk proyek multi-modul, root build script biasanya hanya berisi konfigurasi bersama:

kotlin build.gradle.kts (root)
plugins {
    kotlin("jvm") version "2.0.21" apply false
}

subprojects {
    repositories {
        mavenCentral()
    }
}

Setiap subproyek kemudian memiliki build.gradle.kts sendiri yang mendaftarkan plugin kotlin("jvm") tanpa versi (versi di-root).

Demonstrasi Struktur Proyek #

Kode berikut mencantumkan layout proyek Gradle standar sebagai referensi visual yang dapat diverifikasi.

kotlin
fun main() {
    println("=== Struktur Proyek Gradle ===")
    println("Layout standar Gradle (convention over configuration):")
    println()
    println("  my-app/")
    println("  ├── settings.gradle.kts     (root settings, daftar subproyek)")
    println("  ├── build.gradle.kts         (root build script)")
    println("  ├── gradle.properties         (properti global: org.gradle.jvmargs=...)")
    println("  ├── gradle/")
    println("  │   ├── wrapper/              (gradle-wrapper.jar + properties)")
    println("  │   └── libs.versions.toml    (version catalog)")
    println("  ├── gradlew, gradlew.bat      (wrapper script)")
    println("  └── src/")
    println("      ├── main/")
    println("      │   ├── kotlin/com/example/App.kt")
    println("      │   ├── java/com/example/Helper.java   (opsional)")
    println("      │   └── resources/application.conf")
    println("      └── test/")
    println("          ├── kotlin/com/example/AppTest.kt")
    println("          └── resources/application-test.conf")
    println()
    println("Multi-module: tambahkan subproyek di settings.gradle.kts")
    println("  include(\":app\", \":core\", \":web\")")
}

Output yang Dihasilkan:

text
=== Struktur Proyek Gradle ===
Layout standar Gradle (convention over configuration):

  my-app/
  ├── settings.gradle.kts     (root settings, daftar subproyek)
  ├── build.gradle.kts         (root build script)
  ├── gradle.properties         (properti global: org.gradle.jvmargs=...)
  ├── gradle/
  │   ├── wrapper/              (gradle-wrapper.jar + properties)
  │   └── libs.versions.toml    (version catalog)
  ├── gradlew, gradlew.bat      (wrapper script)
  └── src/
      ├── main/
      │   ├── kotlin/com/example/App.kt
      │   ├── java/com/example/Helper.java   (opsional)
      │   └── resources/application.conf
      └── test/
          ├── kotlin/com/example/AppTest.kt
          └── resources/application-test.conf

Multi-module: tambahkan subproyek di settings.gradle.kts
  include(":app", ":core", ":web")

Mari kita telaah kode di atas:

  1. Layout src/main/kotlin: plugin Kotlin Gradle mendaftarkan source set main dengan path src/main/kotlin. Kode .kt di sini dikompilasi ke build/classes/kotlin/main.
  2. Layout src/main/java: plugin java (otomatis diterapkan plugin Kotlin) menambahkan src/main/java. Kode Java dan Kotlin dapat saling memanggil di proyek yang sama.
  3. Layout src/main/resources: file non-kode (config, gambar, template) disalin apa adanya ke build/resources/main dan disertakan di classpath runtime.
  4. Layout test: struktur paralel di src/test/. Output kompilasi test tidak disertakan di JAR produksi.

Multi-Modul #

Untuk aplikasi yang berkembang, memisahkan kode ke modul-modul terpisah memberi beberapa manfaat:

  • Build inkremental lebih cepat (perubahan di satu modul tidak mengompilasi ulang semua).
  • Batas dependensi eksplisit (modul web boleh pakai modul core, tetapi tidak sebaliknya).
  • Dukungan multiplatform yang lebih baik (modul core bisa multiplatform, web JVM).
text
my-app/
├── settings.gradle.kts        # include(":app", ":core", ":web")
├── app/
│   ├── build.gradle.kts       # implementation(project(":core"))
│   └── src/main/kotlin/...
├── core/
│   ├── build.gradle.kts       # implementation(project(":web"))
│   └── src/main/kotlin/...
└── web/
    ├── build.gradle.kts
    └── src/main/kotlin/...

Untuk mengonsumsi modul lain:

kotlin app/build.gradle.kts
dependencies {
    implementation(project(":core"))
    implementation(project(":web"))
}

gradle.properties #

File gradle.properties di root berisi properti global yang memengaruhi perilaku Gradle:

text gradle.properties
org.gradle.jvmargs=-Xmx2g -XX:+UseZGC
org.gradle.parallel=true
org.gradle.caching=true
org.gradle.configuration-cache=true
kotlin.code.style=official

Empat properti pertama mengatur performa; kotlin.code.style memilih gaya default formatter IntelliJ.

Source Set Kustom #

Untuk struktur yang berbeda dari konvensi default, Gradle mengizinkan kita menyesuaikan source set:

kotlin build.gradle.kts — source set kustom
sourceSets {
    val main by getting {
        kotlin.srcDir("src/main/kotlin")
        kotlin.srcDir("src/generated/kotlin")
        resources.srcDir("src/main/config")
    }
    val test by getting {
        kotlin.srcDir("src/test/kotlin")
        kotlin.srcDir("src/integrationTest/kotlin")
    }
}

Custom source set berguna bila proyek memiliki kode yang dihasilkan (mis. oleh KSP, Dagger, atau protobuf) yang harus berada di direktori terpisah agar tidak tercampur dengan kode tulisan tangan.

Referensi Lanjutan #

  • Gradle — panduan resmi Kotlin + Gradle untuk struktur project dan source set
  • Gradle User Guide — buku panduan Gradle yang merinci layout direktori dan multi-project build

Penutup #

Struktur proyek Gradle yang konsisten adalah fondasi kolaborasi tim. Konvensi src/main/kotlin dan src/test/kotlin dikenali oleh semua IDE Kotlin, sehingga developer baru dapat segera produktif. Pada chapter berikutnya kita akan membahas blok dependencies yang berada di dalam build.gradle.kts dan memilih configuration yang tepat untuk setiap dependensi.