Gradle 5 mit Kotlin DSL in Multi-Project Build


Gradle 5 mit Kotlin DSL in Multi-Project Build

Um ein Java oder Kotlin Projekt aufzusetzen muss man sich für ein Build-Management-Tool entscheiden. Für einen Test den ich durchführen möchte musste ich das gestern tun und habe mich diesmal für Kotlin und Gradle entschieden. Außerdem möchte ich Spring und Spring Dependency Management einsetzen und das ganze soll als Multi-Project-Build funktionieren. Dabei bin ich auf die relativ neue Möglichkeit gestoßen Gradle mit der Kotlin DSL zu konfigurieren.

Ich habe mir folgende Fragen gestellt: Wie konfiguriere ich möglichst viel im Parent-Projekt durch Vererbung? Und wie kann ich Dependency Management (Versionen), so wie in Maven, durch Spring durchführen lassen? Das Ergebnis möchte ich hier vorstellen.

Grundgerüst

Zuerst legt man sich ein neues Projekt mit folgendem Befehl an:

gradle init --type=kotlin-application --dsl kotlin

Dadurch wird ein Grundgerüst des Projekts erstellt und in der Kotlin DSL die benötigten Einstellungen in der build.gradle.kts durchgeführt um in Kotlin entwickeln zu können.

Multi-Module

Um daraus ein Multi-Project Build zu machen, sollten die Sub-Projects in form von leeren Ordnern angelegt werden. In diesem Fall „message-dashboard“ und „message-factory“.

mkdir message-dashboard
mkdir message-factory

Anschließend kopieren wir den src-Ordner aus dem root-Project in die Sub-Projects um die für die Entwicklung nötige Ordnerstruktur zu erhalten. Anschließend löschen wir den src-Ordner im root-Project.

cp -r ./src ./message-dashboard/src
cp -r ./src ./message-factory/src
rm -rf src

In jedem sub-Project muss nun eine build.gradle.kts angelegt werden.

touch message-dashboard/build.gradle.kts
touch message-factory/build.gradle.kts

In der settings.gradle fügt man nun die Sub-Projects hinzu.

rootProject.name = "gradle-kotlin-spring"
include("message-factory")
include("message-dashboard")

Das Projekt sollte nun beim ausführen von Gradle keine Fehler mehr werfen, den code in den Sub-Projects allerdings noch nicht verarbeiten. Dafür muss die build.gradle.kts folgendermaßen verändert werden:

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
    // Apply the Kotlin JVM plugin to add support for Kotlin on the JVM.
    kotlin("jvm") version "1.3.11" apply false
}
allprojects {
    group = "de.mrclrchtr.education"
    version = "1.0-SNAPSHOT"
    repositories {
        jcenter()
    }
}
subprojects {
    tasks.withType<KotlinCompile>().configureEach {
        println("Configuring $name in project ${project.name}...")
        kotlinOptions {
            jvmTarget = "1.8"
            freeCompilerArgs = listOf("-Xjsr305=strict")
        }
    }
}

In plugins wurde die neue Schreibweise des Kotlin Plugins hinzugefügt. In allpropjects wird die Group und die Version für alle Projekte festgelegt. In subprojects wird der KotlinCompiler konfiguriert.

Kotlin Logo

In den build.gradle.kts der Sub-Projects muss folgendes hinzugefügt werden:

plugins {
    kotlin("jvm")
}
dependencies {
    compile(kotlin("stdlib-jdk8"))
    // Use the Kotlin test library.
    testImplementation("org.jetbrains.kotlin:kotlin-test")
    // Use the Kotlin JUnit integration.
    testImplementation("org.jetbrains.kotlin:kotlin-test-junit")
}

Hier wird das Kotlin-Plugin aktiviert und die individuellen Dependencies hinzugefügt. Nun ist das Projekt ein Multi-Project-Build.

Spring & Spring Dependency Management

Um Spring Dependency Management zu aktivieren wird wieder die Gradle-Config des Root-Projects angepasst.

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import io.spring.gradle.dependencymanagement.dsl.DependencyManagementExtension
plugins {
    base
    kotlin("jvm") version "1.3.11" apply false
    id("org.jetbrains.kotlin.plugin.spring") version "1.3.11" apply false
    id("org.springframework.boot") version "2.1.1.RELEASE" apply false
}
allprojects {
    group = "de.mrclrchtr.education"
    version = "1.0-SNAPSHOT"
    repositories {
        jcenter()
    }
}
subprojects {
    apply(plugin = "org.springframework.boot")
    println("Enabling Kotlin Spring plugin in project ${project.name}...")
    apply(plugin = "org.jetbrains.kotlin.plugin.spring")
    println("Enabling Spring Boot Dependency Management in project ${project.name}...")
    apply(plugin = "io.spring.dependency-management")
    the<DependencyManagementExtension>().apply {
        imports {
            mavenBom(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES)
        }
    }
    tasks.withType<KotlinCompile>().configureEach {
        println("Configuring $name in project ${project.name}...")
        kotlinOptions {
            jvmTarget = "1.8"
            freeCompilerArgs = listOf("-Xjsr305=strict")
        }
    }
    tasks.withType<Test> {
        useJUnitPlatform()
    }
}
dependencies {
    // Make the root project archives configuration depend on every subproject
    subprojects.forEach {
        archives(it)
    }
}

Es werden die Plugins org.jetbrains.kotlin.plugin.spring und org.springframework.boot hinzugefügt und anschließend in subprojects aktiviert. Zusätzlich wird das Dependency Management mit der DependencyManagementExtension durchgeführt. In den Sub-Projects können nun einfach Spring Dependencies ohne Angabe von Versionen wie in Folgendem Beispiel genutzt werden.

plugins {
    kotlin("jvm")
}
dependencies {
    compile(kotlin("stdlib-jdk8"))
    compile("org.springframework.boot:spring-boot-starter-web")
    compile("org.springframework.boot:spring-boot-starter-actuator")
    // Use the Kotlin test library.
    testImplementation("org.jetbrains.kotlin:kotlin-test")
    // Use the Kotlin JUnit integration.
    testImplementation("org.jetbrains.kotlin:kotlin-test-junit")
}


Das Ergebnis mit Beispielanwendung und weiteren Erweiterungen ist auf GitHub zu finden.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert