dependencies {
implementation("org.apache.slf4j:slf4j-api:1.7.25")
}
08 February 2022
Tags: gradle micronaut version catalog
With the release of Gradle 7.4, Micronaut users now have an interesting option to manage their dependencies: using Gradle’s version catalogs. Indeed, for a few releases already, Micronaut has shipped its own version catalog alongside its BOM.
Let’s explore how to use it and what’s the benefit.
In a nutshell, a version catalog allows centralizing dependency versions in a single place. Instead a build script, a typical dependency declaration looks like this:
dependencies {
implementation("org.apache.slf4j:slf4j-api:1.7.25")
}
With a version catalog, the declaration looks like this:
dependencies {
implementation(libs.slf4j)
}
And the dependency coordinates are defined in the gradle/libs.versions.toml
file:
[versions]
slf4j = "1.7.25"
[libraries]
slf4j = { module = "org.apache.slf4j", version.ref = "slf4j" }
There are a couple of advantages in doing so:
dependency versions are centralized in this TOML file
the catalogs create "type safe accessors" which are completed by the IDE (although to my knowledge completion is only supported by IntelliJ IDEA with the Kotlin DSL)
You can read a more complete description about version catalogs in this blog post I wrote a few months ago.
In addition, frameworks like Micronaut can publish version catalogs, which are then usable in your projects. You can then think of the Micronaut version catalog as a list of dependencies to pick up from: you don’t have to think about a version to choose, you can simply use the "recommendation" from Micronaut, but you don’t have to remember the dependency coordinates either.
Let’s start with a project that you can generate using the Micronaut CLI:
mn create-app catalog
(alternatively, download the project using Micronaut Launch)
Open the generated project and update the Gradle version by changing the gradle/gradle-wrapper.properties
file:
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
Now, in order to import the Micronaut version catalog, add this to your settings.gradle
file:
dependencyResolutionManagement {
repositories {
mavenCentral()
}
versionCatalogs {
create("mn") {
from("io.micronaut:micronaut-bom:${micronautVersion}")
}
}
}
Here, we’re creating a new version catalog called mn
.
Internally, Gradle will automatically download the catalog which is published at the same GAV coordinates as its BOM as a TOML file and expose it to your build scripts.
Let’s open our build.gradle
file.
By default it defines the following dependencies:
dependencies {
annotationProcessor("io.micronaut:micronaut-http-validation")
implementation("io.micronaut:micronaut-http-client")
implementation("io.micronaut:micronaut-jackson-databind")
implementation("io.micronaut:micronaut-runtime")
implementation("jakarta.annotation:jakarta.annotation-api")
runtimeOnly("ch.qos.logback:logback-classic")
implementation("io.micronaut:micronaut-validation")
}
Now, we can replace this with the following:
dependencies {
annotationProcessor(mn.micronaut.http.validation)
implementation(mn.micronaut.http.client)
implementation(mn.micronaut.jackson.databind)
implementation(mn.micronaut.runtime)
implementation(mn.jakarta.annotation.api)
runtimeOnly(mn.logback)
implementation(mn.micronaut.validation)
}
What happened here?
Basically, we replaced hardcoded dependency coordinates with references to the mn
version catalog.
It’s particularly interesting if you are using the Kotlin DSL as I mentioned earlier, because in this case, the dependency notations are type-safe: you can’t make a typo in dependency coordinates, and you get completion:
Nice!
Version catalogs will probably be enabled by default in future releases of Micronaut, which means that projects created via Micronaut Launch or the CLI tool would automatically use the catalog, so you don’t have to do the conversion described in this blog post. Stay tuned!