Search

Dark theme | Light theme
Showing posts with label GradleGoodness:Kotlin. Show all posts
Showing posts with label GradleGoodness:Kotlin. Show all posts

November 8, 2022

Gradle Goodness: Defining Plugin Versions Using Version Catalog

A version catalog in Gradle is a central place in our project where we can define dependency references with their version or version rules. A dependency reference is defined using an identifier with a corresponding dependency definition containing the coordinates of the dependency. Now we can reference the dependency using the identifier in for example a dependency configuration, e.g. implementation(libs.spring.core). If there is a version change we want to apply we only have to make the change in our version catalog. An added bonus is that Gradle generates type safe accessors for the identifier we use in our version catalog, so we can get code completion in our IntelliJ IDEA when we want to reference a dependency from the version catalog.

Besides dependencies we need to build and test our software we can also include definitions for Gradle plugins including their version. Normally we reference a Gradle plugin using the id and version. For example in the following code block we include 4 Gradle plugins of which 3 are identified by an id:

plugins {
	`java` // Default Gradle Java plugin
	
	// Include 3 third-party Gradle plugins
	id("org.springframework.boot") version "2.7.5"
	id("io.spring.dependency-management") version "1.0.15.RELEASE"
	id("org.asciidoctor.jvm.convert") version "3.2.0"
}

We can replace these plugin references with version catalog defined values. First we must create the file gradle/libs.version.toml in our project directory. We might already have such file with definitions for the dependencies we use in our build and tests. Next we must add a section [plugins] where we can define our plugin dependencies. We can use the full power of the version catalog here, the only thing we need to remember is to use the id property of we use the longer notation option. With the shorthand notation we can simply define a string value with the id of the plugin, a colon (:) and the version.

In the following example libs.versions.toml file we defined our 3 third-party plugins using several notations:

# File: gradle/libs.versions.toml
[versions]
# Define version we can use as version.ref in [plugins]
asciidoctor = "3.2.0" 

[plugins]
# We can use shorthand notation with the plugin id and version.
spring-boot = "org.springframework.boot:2.7.5"

# We can use the longer notation option where we set 
# the id and version for the plugin.
spring-dep-mgmt = { id = "io.spring.dependency-management", version = "1.0.15.RELEASE" }

# Here we use the longer notation and version.ref to reference
# the version defined in the [versions] section.
asciidoctor-jvm = { id = "org.asciidoctor.jvm.convert", version.ref = "asciidoctor" }

We only have to change our plugins block in our build file. We use the method alias to reference our version catalog definitions. In IntelliJ IDEA we even get code completion when start typing. The following code shows how we include the plugins:

plugins {
	`java` // Default Gradle Java plugin
	
	// Using alias we can reference the plugin id and version
	// defined in the version catalog.
	// Notice that hyphens (-) used as separator in the identifier
	// are translated into type safe accessors for each subgroup.
	alias(libs.plugins.spring.boot)
	alias(libs.plugins.spring.dep.mgmt)
	alias(libs.plugins.asciidoctor.jvm)
}

The version catalog is a powerful feature of Gradle. It allows to have a single place in our project where we define dependency coordinates and we get type safe accessors methods to have code completion in IntelliJ IDEA.

Written with Gradle 7.5.1.

March 5, 2021

Gradle Goodness: Enabling Preview Features For Java

Java introduced preview features in the language since Java 12. This features can be tried out by developers, but are still subject to change and can even be removed in a next release. By default the preview features are not enabled when we want to compile and run our Java code. We must explicitly specify that we want to use the preview feature to the Java compiler and Java runtime using the command-line argument --enable-preview. In Gradle we can customize our build file to enable preview features. We must customize tasks of type JavaCompile and pass --enable-preview to the compiler arguments. Also tasks of type Test and JavaExec must be customized where we need to add the JVM argument --enable-preview.

In the following Gradle build script written in Kotlin we have a Java project written with Java 15 where we reconfigure the tasks to enable preview features:

plugins {
    java
    application
}

repositories {
    mavenCentral()
}

dependencies {
    testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.1")
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.7.1")
}

application {
    mainClass.set("mrhaki.Patterns")
}

tasks {
    val ENABLE_PREVIEW = "--enable-preview"

    // In our project we have the tasks compileJava and
    // compileTestJava that need to have the
    // --enable-preview compiler arguments.
    withType<JavaCompile>() {
        options.compilerArgs.add(ENABLE_PREVIEW)

        // Optionally we can show which preview feature we use.
        options.compilerArgs.add("-Xlint:preview")

        // Explicitly setting compiler option --release
        // is needed when we wouldn't set the
        // sourceCompatiblity and targetCompatibility
        // properties of the Java plugin extension.
        options.release.set(15)
    }

    // Test tasks need to have the JVM argument --enable-preview.
    withType<Test>() {
        useJUnitPlatform()
        jvmArgs.add(ENABLE_PREVIEW)
    }

    // JavaExec tasks need to have the JVM argument --enable-preview.
    withType<JavaExec>() {
        jvmArgs.add(ENABLE_PREVIEW)
    }
}

Written with Gradle 6.8.3