# Gradle Build Refactoring Guide ## Overview This guide documents the comprehensive Gradle build optimization completed in Phases 1-5, including practical refactoring patterns for all remaining modules. --- ## ✅ Completed Changes ### Phase 1: Bundles & Version Catalog **File:** `gradle/libs.versions.toml` #### Added Missing Libraries: - `slf4j-api` (version 2.0.16) - `kotlin-reflect` (uses kotlin version reference) #### Added 5 New Complete Bundles: 1. **`ktor-server-complete`** - Full Ktor server stack (14 dependencies) - Includes: core, netty, content-negotiation, serialization, status-pages, cors, default-headers, auth, auth-jwt, call-logging, metrics-micrometer, openapi, swagger, rate-limit 2. **`spring-boot-service-complete`** - Full Spring Boot service stack (12 dependencies) - Includes: web, validation, actuator, security, oauth2-client, oauth2-resource-server, oauth2-jose, data-jpa, data-redis, micrometer-prometheus, tracing-bridge-brave, zipkin-reporter-brave 3. **`database-complete`** - Complete database stack (8 dependencies) - Includes: exposed-core, exposed-dao, exposed-jdbc, exposed-kotlin-datetime, postgresql-driver, hikari-cp, flyway-core, flyway-postgresql 4. **`testing-kmp`** - KMP testing stack (8 dependencies) - Includes: kotlin-test, junit-jupiter-api, junit-jupiter-engine, junit-jupiter-params, junit-platform-launcher, mockk, assertj-core, kotlinx-coroutines-test 5. **`monitoring-complete`** - Complete monitoring stack (8 dependencies) - Includes: actuator, micrometer-prometheus, tracing-bridge-brave, zipkin-reporter-brave, zipkin-sender-okhttp3, kotlin-logging-jvm, logback-classic, slf4j-api ### Phase 2: Root Build File **File:** `build.gradle.kts` #### Enhancements: - ✅ Added `allprojects` configuration block with group, version, and common repositories - ✅ Added dependency-analysis plugin (version 2.6.1) - ✅ Added versions plugin (version 0.51.0) - ✅ Updated wrapper task to Gradle 9.1.0 ### Phase 3: Convention Plugins **Directory:** `buildSrc/src/main/kotlin/` #### Created 3 Convention Plugins: 1. **`ktor-server-conventions.gradle.kts`** - For Ktor server modules - Applies: kotlin-jvm, ktor, serialization plugins - Configures: Java 21 toolchain, compiler options, test configuration 2. **`spring-boot-service-conventions.gradle.kts`** - For Spring Boot service modules - Applies: kotlin-jvm, spring-boot, dependency-management, kotlin-spring, kotlin-jpa plugins - Configures: Java 21 toolchain, compiler options, test configuration, JPA all-open 3. **`kotlin-multiplatform-conventions.gradle.kts`** - For KMP modules (clients, shared) - Applies: kotlin-multiplatform, serialization plugins - Configures: Java 21 toolchain, compiler options for all targets ### Phase 5: Gradle Properties **File:** `gradle.properties` #### Added Kotlin Compiler Optimizations: ```properties 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 **Applies to:** Gateway, Auth-Server, Monitoring-Server, Ping-Service, and all Spring Boot-based services #### Before: ```kotlin 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 { 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") // ... more dependencies } ``` #### After: ```kotlin plugins { id("spring-boot-service-conventions") } springBoot { mainClass.set("com.example.MainKt") } dependencies { // Platform BOM implementation(platform(projects.platform.platformBom)) // Project dependencies 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) // Specific dependencies implementation(libs.kotlin.reflect) // ... other specific dependencies // Tests testImplementation(projects.platform.platformTesting) testImplementation(libs.bundles.testing.jvm) } ``` **Benefits:** - ~30-40% reduction in lines of code - No manual toolchain/compiler configuration - Centralized dependency management through bundles - Consistent configuration across all Spring Boot services --- ### Pattern 2: Ktor Server Services **Applies to:** Any Ktor-based backend services (currently not in project, but pattern available) #### Usage: ```kotlin plugins { id("ktor-server-conventions") } ktor { fatJar { archiveFileName.set("service-name.jar") } } dependencies { implementation(platform(projects.platform.platformBom)) // Use complete Ktor bundle implementation(libs.bundles.ktor.server.complete) // Or use specific bundles for fine-grained control implementation(libs.bundles.ktor.server.common) implementation(libs.bundles.ktor.server.security) implementation(libs.bundles.ktor.server.observability) // Database 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 Modules **Applies to:** clients/app, clients/ping-feature, clients/auth-feature, clients/shared, core/core-utils, core/core-domain #### Before: ```kotlin 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 { compilerOptions { jvmTarget.set(JvmTarget.JVM_21) freeCompilerArgs.addAll("-opt-in=kotlin.RequiresOptIn") } } ``` #### After: ```kotlin plugins { id("kotlin-multiplatform-conventions") alias(libs.plugins.composeMultiplatform) alias(libs.plugins.composeCompiler) } kotlin { jvm() js(IR) { browser() } sourceSets { commonMain.dependencies { // Use bundles implementation(libs.bundles.kotlinx.core) implementation(libs.bundles.ktor.client.common) implementation(libs.bundles.compose.common) // Compose (from plugin) implementation(compose.runtime) implementation(compose.foundation) implementation(compose.material3) } } } ``` **Benefits:** - Removes toolchain and compiler configuration boilerplate - Bundles group related dependencies - Cleaner and more maintainable --- ## 📋 Module Refactoring Checklist ### Infrastructure Modules #### ✅ Gateway (Completed - Example) - Pattern: Spring Boot Service - Lines reduced: 113 → 90 (20%) #### 🔲 Auth-Server - Pattern: Spring Boot Service - Replace plugins with `spring-boot-service-conventions` - Use `spring-boot-service-complete`, `resilience`, `logging` bundles #### 🔲 Messaging-Config - Pattern: Spring Boot Service - Use `spring-boot-service-complete`, `kafka-config` bundles #### 🔲 Redis-Cache - Pattern: Spring Boot Service - Use `spring-boot-service-complete`, `redis-cache` bundles #### 🔲 Redis-Event-Store - Pattern: Spring Boot Service - Use `spring-boot-service-complete`, `redis-cache` bundles #### 🔲 Monitoring-Server - Pattern: Spring Boot Service - Use `spring-boot-service-complete`, `monitoring-complete` bundles ### Service Modules #### ✅ Ping-Service (Completed - Example) - Pattern: Spring Boot Service - Lines reduced: 79 → 50 (37%) #### 🔲 Ping-API - Pattern: Kotlin Multiplatform (if KMP) or Kotlin JVM - Use `kotlinx-core` bundle ### Client Modules #### 🔲 clients/app - Pattern: Kotlin Multiplatform - Use `kotlin-multiplatform-conventions` - Use `kotlinx-core`, `compose-common` bundles #### 🔲 clients/ping-feature - Pattern: Kotlin Multiplatform - Already uses some bundles, ensure all are used #### 🔲 clients/auth-feature - Pattern: Kotlin Multiplatform - Use `kotlin-multiplatform-conventions` - Use `kotlinx-core`, `ktor-client-common`, `compose-common` bundles #### 🔲 clients/shared modules - Pattern: Kotlin Multiplatform - Use `kotlin-multiplatform-conventions` - Use `kotlinx-core` bundle ### Core & Platform Modules #### 🔲 core/core-utils - Pattern: Kotlin Multiplatform - Use `kotlin-multiplatform-conventions` - Use `kotlinx-core` bundle #### 🔲 core/core-domain - Pattern: Kotlin Multiplatform - Use `kotlin-multiplatform-conventions` - Use `kotlinx-core` bundle #### 🔲 platform/platform-testing - Pattern: Kotlin JVM - Use `testing-kmp` or `testing-jvm` bundles --- ## 🚀 Recommended Build Commands ### Dependency Analysis ```bash ./gradlew buildHealth ``` ### Check for Dependency Updates ```bash ./gradlew dependencyUpdates ``` ### Build with Scan ```bash ./gradlew build --scan ``` ### Dry Run for Task Dependencies ```bash ./gradlew :services:ping:ping-service:build --dry-run ``` ### Measure Build Performance ```bash time ./gradlew clean build ``` --- ## 📊 Expected Benefits ### Build Performance - **Incremental compilation**: ~20-40% faster rebuilds - **Configuration cache**: ~30-50% faster configuration phase (when enabled) - **Parallel execution**: Better utilization of multi-core systems ### Maintainability - **Reduced duplication**: Convention plugins eliminate repetitive configuration - **Centralized versioning**: Single source of truth in `libs.versions.toml` - **Easier updates**: Update dependency versions in one place ### Code Metrics - **Average reduction**: 20-40% fewer lines per build file - **Consistency**: All modules follow same patterns - **Type safety**: Version catalog provides IDE support and compile-time checking --- ## ⚠️ Important Notes ### Configuration Cache Currently disabled due to JS test serialization issues. Can be re-enabled once resolved: ```properties org.gradle.configuration-cache=true ``` ### WASM Support Optional, enable via: ```properties enableWasm=true ``` ### Incremental Refactoring - Refactor one module at a time - Test after each change - Use demonstrated examples as templates --- ## 📚 References - **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