13 KiB
Gradle Build Refactoring-Leitfaden
Überblick
Dieser Leitfaden dokumentiert die umfassende Gradle Build-Optimierung, die in den Phasen 1-5 abgeschlossen wurde, einschließlich praktischer Refactoring-Patterns für alle verbleibenden Module.
✅ Abgeschlossene Änderungen
Phase 1: Bundles & Version Catalog
Datei: gradle/libs.versions.toml
Fehlende Bibliotheken hinzugefügt:
slf4j-api(Version 2.0.16)kotlin-reflect(verwendet Kotlin-Versionsreferenz)
5 neue Complete Bundles hinzugefügt:
-
ktor-server-complete- Vollständiger Ktor-Server-Stack (14 Abhängigkeiten)- Enthält: core, netty, content-negotiation, serialization, status-pages, cors, default-headers, auth, auth-jwt, call-logging, metrics-micrometer, openapi, swagger, rate-limit
-
spring-boot-service-complete- Vollständiger Spring Boot Service-Stack (12 Abhängigkeiten)- Enthält: web, validation, actuator, security, oauth2-client, oauth2-resource-server, oauth2-jose, data-jpa, data-redis, micrometer-prometheus, tracing-bridge-brave, zipkin-reporter-brave
-
database-complete- Vollständiger Datenbank-Stack (8 Abhängigkeiten)- Enthält: exposed-core, exposed-dao, exposed-jdbc, exposed-kotlin-datetime, postgresql-driver, hikari-cp, flyway-core, flyway-postgresql
-
testing-kmp- KMP-Test-Stack (8 Abhängigkeiten)- Enthält: kotlin-test, junit-jupiter-api, junit-jupiter-engine, junit-jupiter-params, junit-platform-launcher, mockk, assertj-core, kotlinx-coroutines-test
-
monitoring-complete- Vollständiger Monitoring-Stack (8 Abhängigkeiten)- Enthält: actuator, micrometer-prometheus, tracing-bridge-brave, zipkin-reporter-brave, zipkin-sender-okhttp3, kotlin-logging-jvm, logback-classic, slf4j-api
Phase 2: Root Build-Datei
Datei: build.gradle.kts
Verbesserungen:
- ✅
allprojects-Konfigurationsblock mit Gruppe, Version und gemeinsamen Repositories hinzugefügt - ✅ Dependency-Analysis-Plugin hinzugefügt (Version 2.6.1)
- ✅ Versions-Plugin hinzugefügt (Version 0.51.0)
- ✅ Wrapper-Task auf Gradle 9.1.0 aktualisiert
Phase 3: Convention Plugins
Verzeichnis: buildSrc/src/main/kotlin/
3 Convention Plugins erstellt:
-
ktor-server-conventions.gradle.kts- Für Ktor-Server-Module
- Wendet an: kotlin-jvm, ktor, serialization Plugins
- Konfiguriert: Java 21 Toolchain, Compiler-Optionen, Test-Konfiguration
-
spring-boot-service-conventions.gradle.kts- Für Spring Boot Service-Module
- Wendet an: kotlin-jvm, spring-boot, dependency-management, kotlin-spring, kotlin-jpa Plugins
- Konfiguriert: Java 21 Toolchain, Compiler-Optionen, Test-Konfiguration, JPA All-Open
-
kotlin-multiplatform-conventions.gradle.kts- Für KMP-Module (clients, shared)
- Wendet an: kotlin-multiplatform, serialization Plugins
- Konfiguriert: Java 21 Toolchain, Compiler-Optionen für alle Targets
Phase 5: Gradle Properties
Datei: gradle.properties
Kotlin-Compiler-Optimierungen hinzugefügt:
kotlin.incremental=true
kotlin.incremental.multiplatform=true
kotlin.incremental.js=true
kotlin.caching.enabled=true
kotlin.compiler.execution.strategy=in-process
kotlin.compiler.preciseCompilationResultsBackup=true
kotlin.stdlib.default.dependency=true
🔄 Refactoring-Patterns
Pattern 1: Spring Boot Services
Gilt für: Gateway, Auth-Server, Monitoring-Server, Ping-Service und alle Spring Boot-basierten Services
Vorher:
plugins {
alias(libs.plugins.kotlinJvm)
alias(libs.plugins.kotlinSpring)
alias(libs.plugins.spring.boot)
alias(libs.plugins.spring.dependencyManagement)
}
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(21))
}
}
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
compilerOptions {
freeCompilerArgs.addAll("-Xjsr305=strict")
jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_21)
}
}
springBoot {
mainClass.set("com.example.MainKt")
buildInfo()
}
dependencies {
implementation(libs.spring.boot.starter.web)
implementation(libs.spring.boot.starter.validation)
implementation(libs.spring.boot.starter.actuator)
implementation(libs.spring.boot.starter.security)
implementation(libs.spring.boot.starter.oauth2.client)
implementation(libs.spring.boot.starter.oauth2.resource.server)
implementation(libs.resilience4j.spring.boot3)
implementation(libs.resilience4j.reactor)
implementation(libs.spring.boot.starter.aop)
implementation(libs.jackson.module.kotlin)
implementation(libs.jackson.datatype.jsr310)
implementation("ch.qos.logback:logback-classic")
implementation("ch.qos.logback:logback-core")
implementation("org.slf4j:slf4j-api")
// ... weitere Abhängigkeiten
}
Nachher:
plugins {
id("spring-boot-service-conventions")
}
springBoot {
mainClass.set("com.example.MainKt")
}
dependencies {
// Platform BOM
implementation(platform(projects.platform.platformBom))
// Projekt-Abhängigkeiten
implementation(projects.core.coreUtils)
implementation(projects.platform.platformDependencies)
// Complete Bundles
implementation(libs.bundles.spring.boot.service.complete)
implementation(libs.bundles.resilience)
implementation(libs.bundles.jackson.kotlin)
implementation(libs.bundles.logging)
// Spezifische Abhängigkeiten
implementation(libs.kotlin.reflect)
// ... andere spezifische Abhängigkeiten
// Tests
testImplementation(projects.platform.platformTesting)
testImplementation(libs.bundles.testing.jvm)
}
Vorteile:
- ~30-40% Reduktion der Codezeilen
- Keine manuelle Toolchain-/Compiler-Konfiguration
- Zentralisiertes Dependency-Management durch Bundles
- Konsistente Konfiguration über alle Spring Boot Services
Pattern 2: Ktor Server Services
Gilt für: Alle Ktor-basierten Backend-Services (derzeit nicht im Projekt, aber Pattern verfügbar)
Verwendung:
plugins {
id("ktor-server-conventions")
}
ktor {
fatJar {
archiveFileName.set("service-name.jar")
}
}
dependencies {
implementation(platform(projects.platform.platformBom))
// Verwende Complete Ktor Bundle
implementation(libs.bundles.ktor.server.complete)
// Oder verwende spezifische Bundles für feinkörnige Kontrolle
implementation(libs.bundles.ktor.server.common)
implementation(libs.bundles.ktor.server.security)
implementation(libs.bundles.ktor.server.observability)
// Datenbank
implementation(libs.bundles.database.complete)
// Monitoring
implementation(libs.bundles.monitoring.complete)
// Tests
testImplementation(libs.bundles.testing.kmp)
testImplementation(libs.ktor.server.tests)
}
Pattern 3: Kotlin Multiplatform Module
Gilt für: clients/app, clients/ping-feature, clients/auth-feature, clients/shared, core/core-utils, core/core-domain
Vorher:
plugins {
alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.kotlinSerialization)
alias(libs.plugins.composeMultiplatform)
alias(libs.plugins.composeCompiler)
}
kotlin {
jvmToolchain(21)
jvm()
js(IR) { browser() }
sourceSets {
commonMain.dependencies {
implementation(libs.kotlinx.coroutines.core)
implementation(libs.kotlinx.serialization.json)
implementation(libs.kotlinx.datetime)
implementation(libs.ktor.client.core)
implementation(libs.ktor.client.contentNegotiation)
implementation(libs.ktor.client.serialization.kotlinx.json)
implementation(libs.ktor.client.logging)
implementation(libs.ktor.client.auth)
implementation(libs.androidx.lifecycle.viewmodelCompose)
implementation(libs.androidx.lifecycle.runtimeCompose)
}
}
}
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
compilerOptions {
jvmTarget.set(JvmTarget.JVM_21)
freeCompilerArgs.addAll("-opt-in=kotlin.RequiresOptIn")
}
}
Nachher:
plugins {
id("kotlin-multiplatform-conventions")
alias(libs.plugins.composeMultiplatform)
alias(libs.plugins.composeCompiler)
}
kotlin {
jvm()
js(IR) { browser() }
sourceSets {
commonMain.dependencies {
// Verwende Bundles
implementation(libs.bundles.kotlinx.core)
implementation(libs.bundles.ktor.client.common)
implementation(libs.bundles.compose.common)
// Compose (vom Plugin)
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material3)
}
}
}
Vorteile:
- Entfernt Toolchain- und Compiler-Konfiguration-Boilerplate
- Bundles gruppieren verwandte Abhängigkeiten
- Sauberer und wartbarer
📋 Modul-Refactoring-Checkliste
Infrastruktur-Module
✅ Gateway (Abgeschlossen - Beispiel)
- Pattern: Spring Boot Service
- Zeilen reduziert: 113 → 90 (20%)
🔲 Auth-Server
- Pattern: Spring Boot Service
- Ersetze Plugins durch
spring-boot-service-conventions - Verwende
spring-boot-service-complete,resilience,loggingBundles
🔲 Messaging-Config
- Pattern: Spring Boot Service
- Verwende
spring-boot-service-complete,kafka-configBundles
🔲 Redis-Cache
- Pattern: Spring Boot Service
- Verwende
spring-boot-service-complete,redis-cacheBundles
🔲 Redis-Event-Store
- Pattern: Spring Boot Service
- Verwende
spring-boot-service-complete,redis-cacheBundles
🔲 Monitoring-Server
- Pattern: Spring Boot Service
- Verwende
spring-boot-service-complete,monitoring-completeBundles
Service-Module
✅ Ping-Service (Abgeschlossen - Beispiel)
- Pattern: Spring Boot Service
- Zeilen reduziert: 79 → 50 (37%)
🔲 Ping-API
- Pattern: Kotlin Multiplatform (falls KMP) oder Kotlin JVM
- Verwende
kotlinx-coreBundle
Client-Module
🔲 clients/app
- Pattern: Kotlin Multiplatform
- Verwende
kotlin-multiplatform-conventions - Verwende
kotlinx-core,compose-commonBundles
🔲 clients/ping-feature
- Pattern: Kotlin Multiplatform
- Verwendet bereits einige Bundles, stelle sicher, dass alle verwendet werden
🔲 clients/auth-feature
- Pattern: Kotlin Multiplatform
- Verwende
kotlin-multiplatform-conventions - Verwende
kotlinx-core,ktor-client-common,compose-commonBundles
🔲 clients/shared Module
- Pattern: Kotlin Multiplatform
- Verwende
kotlin-multiplatform-conventions - Verwende
kotlinx-coreBundle
Core & Platform Module
🔲 core/core-utils
- Pattern: Kotlin Multiplatform
- Verwende
kotlin-multiplatform-conventions - Verwende
kotlinx-coreBundle
🔲 core/core-domain
- Pattern: Kotlin Multiplatform
- Verwende
kotlin-multiplatform-conventions - Verwende
kotlinx-coreBundle
🔲 platform/platform-testing
- Pattern: Kotlin JVM
- Verwende
testing-kmpodertesting-jvmBundles
🚀 Empfohlene Build-Befehle
Dependency-Analyse
./gradlew buildHealth
Nach Dependency-Updates suchen
./gradlew dependencyUpdates
Build mit Scan
./gradlew build --scan
Dry Run für Task-Abhängigkeiten
./gradlew :services:ping:ping-service:build --dry-run
Build-Performance messen
time ./gradlew clean build
📊 Erwartete Vorteile
Build-Performance
- Inkrementelle Kompilierung: ~20-40% schnellere Rebuilds
- Configuration Cache: ~30-50% schnellere Konfigurationsphase (wenn aktiviert)
- Parallele Ausführung: Bessere Auslastung von Multi-Core-Systemen
Wartbarkeit
- Reduzierte Duplikation: Convention Plugins eliminieren sich wiederholende Konfiguration
- Zentralisierte Versionierung: Single Source of Truth in
libs.versions.toml - Einfachere Updates: Dependency-Versionen an einem Ort aktualisieren
Code-Metriken
- Durchschnittliche Reduktion: 20-40% weniger Zeilen pro Build-Datei
- Konsistenz: Alle Module folgen denselben Patterns
- Type-Safety: Version Catalog bietet IDE-Support und Compile-Time-Checking
⚠️ Wichtige Hinweise
Configuration Cache
Derzeit deaktiviert aufgrund von JS-Test-Serialisierungsproblemen. Kann wieder aktiviert werden, sobald gelöst:
org.gradle.configuration-cache=true
WASM-Unterstützung
Optional, aktivierbar über:
enableWasm=true
Inkrementelles Refactoring
- Ein Modul nach dem anderen refactoren
- Nach jeder Änderung testen
- Demonstrierte Beispiele als Templates verwenden
📚 Referenzen
- Gradle Version Catalogs: https://docs.gradle.org/current/userguide/platforms.html
- Convention Plugins: https://docs.gradle.org/current/samples/sample_convention_plugins.html
- Kotlin DSL: https://docs.gradle.org/current/userguide/kotlin_dsl.html