[RFC] Jar dependencies consolidation
- Dominant language
- Java
- Stars
- 14.9k
- Forks
- 3.5k
- Avg merge
- 1d 4h
- Merged PRs (30d)
- 88
Description
## Abstract
Logstash is shaped as a Gradle multi-project, which contains multiple modules where the same dependency is defined across those different modules. So we end up declaring same dependency but with different versions in any project. For example consider `assertj`:
1. Logstash-core https://github.com/elastic/logstash/blob/8c58270eb14c12f3ffe1ea6a881cfcaf6411fc27/logstash-core/build.gradle#L258
2. qa/integration https://github.com/elastic/logstash/blob/8c58270eb14c12f3ffe1ea6a881cfcaf6411fc27/qa/integration/build.gradle#L34
3. x-pack https://github.com/elastic/logstash/blob/8c58270eb14c12f3ffe1ea6a881cfcaf6411fc27/x-pack/build.gradle#L27
The Gradle’s way (since 7.4) is to define a Gradle Version Catalog in te main project, but Logstash already tracks `jackson` and `jrjackson` dependencies in `versions.yml`, which is a custom catalog that also define Logstash’s version, bundled JDK version and hash code of the JRuby artifact.
## Goal
This document describes the two alternatives to make the team of it and discuss a possible solution to centralize dependencies versions.
### Existing `versions.yml`
This mechanism is already in place for `jrjackson`, and require to use Gradle ext properties and define a variable with the version in every project it’s used, for example:
```groovy
def versionMap = gradle.ext.versions
String jacksonVersion = versionMap['jackson']
dependencies {
implementation "com.fasterxml.jackson.core:jackson-core:${jacksonVersion}"
}
```
### Gradle's Version Catalog
Create a TOML file `gradle/libs.versions.toml` that defines:
```toml
[versions]
assertj = "3.26.3"
jackson = "2.16.2"
log4j = "2.23.1"
[libraries]
# Testing
assertj-core = { module = "org.assertj:assertj-core", version.ref = "assertj" }
# Jackson family (sharing same version)
jackson-core = { module = "com.fasterxml.jackson.core:jackson-core", version.ref = "jackson" }
jackson-databind = { module = "com.fasterxml.jackson.core:jackson-databind", version.ref = "jackson" }
jackson-annotations = { module = "com.fasterxml.jackson.core:jackson-annotations", version.ref = "jackson" }
[bundles]
jackson = ["jackson-core", "jackson-databind", "jackson-annotations"]
```
o use the catalog definition Gradle automatically creates accesses to the the bundles and libraries for example, `logstash-core/build.gradle` could be result in:
```groovy
dependencies {
implementation libs.bundles.jackson // this kicks in all the jackson libs
testImplementation libs.assertj.core
}
```
While `x-pack/build.gradle` becomes:
```groovy
dependencies {
testImplementation libs.assertj.core // Same version as logstash-core!
}
```
## Analysis
Using the already existing harness from `versions.yml`:
- ➕ is already in place and proven.
- ➖ no IDE support
- ➖ no standard way of doing things, so newcomers has to know it, instead of relay on standard mechanisms already well known.
- ➕ central point to handle all versioning related question for Logstash, but maybe increase too much it’s scope
Using the Gradle ‘s version catalog:
- ➕ standard ways on doing things
- ✔️ Requires Gradle 7.4+, but shouldn’t be a problem for us because we should have everything ported to Gradle 8
- ➕ well known mechanism
- ➖ could create confusion with versions.yml
- ➕ permit an incremental migration, having jar dependencies in this catalog and the rest in `versions.yml`.
Contributor guide
Assessment
This issue has not been assessed yet.