running `./gradlew dependencies` i get something l...
# dependency-management
b
running
./gradlew dependencies
i get something like:
Copy code
…
testRuntimeClasspath - Runtime classpath of compilation 'test' (target  (jvm)).
…
+--- com.mycompany.mycompany-bom:1.0.62
|    +--- com.microsoft.sqlserver:mssql-jdbc:10.2.1.jre8 (c)
…
+--- org.junit:junit-bom:5.8.2
|    +--- org.junit.jupiter:junit-jupiter-api:5.8.2 (c)
|    +--- org.junit.jupiter:junit-jupiter-engine:5.8.2 (c)
…
testRuntimeOnlyDependenciesMetadata
+--- com.microsoft.sqlserver:mssql-jdbc FAILED
+--- org.junit.jupiter:junit-jupiter-engine FAILED
\--- org.spekframework.spek2:spek-runner-junit5:2.0.18
what exactly does
testRuntimeOnlyDependenciesMetadata
mean? what does it mean for these dependencies (both of which have versions coming in via a BOM) to be marked FAILED?
v
It is a configuration of the Kotlin Gradle plugin, that serves for resolving Kotlin metadata. The configuration extends some
api
and
implementation
configurations from "fragements", whatever that is. Obviously where those dependencies are declared and thus inherited from, the BOMs defining their version seem not to be declared too. So when it is tried to resolve those dependencies, it fails as no version information is defined.
b
ah! yes, so it seems to be happening because i have:
Copy code
dependencies {
    // Import BOMs as gradle platforms
    annotationProcessor(platform(libs.spring.boot.bom))
    implementation(platform(libs.spring.boot.bom))
    implementation(platform(libs.fundamentals.bom))
...
which results in them being available in `implementation`/`testImplementation` configurations, but not in `runtimeOnly`/`testRuntimeOnly` to avoid the error i can do
Copy code
runtimeOnly(platform(libs.fundamentals.bom))
    runtimeOnly(platform(libs.spring.boot.bom))
but is there any reason to actually do that? the expected version seems to be resolved at runtime no matter what the dependency configuration reports
if so… is there any reason not to follow the proposed solution here
Copy code
subprojects { // assuming we only have Java sub projects
   dependencies {
      configurations.each { add(it.name, platform(project(':my-platform'))) }
   }
}
v
but is there any reason to actually do that? the expected version seems to be resolved at runtime no matter what the dependency configuration reports
I have no idea what this configuration is used for, you need to all the Kotlin guys, but I'd expect that it is needed for something or it would not be there.
if so… is there any reason not to follow the proposed solution here
Multiple, for example
.each
only handles the currently existing configurations,
.configureEach
or .
all
would also handle ones added later. And more important almost any usage of a
subprojects
or
allprojects
block is bad for multiple reasons like introducing project coupling which defeats more sophisticated features like parallel execution and configuration cache, and it makes the build harder to maintain and understand.
b
i guess it’s a more general question outside of the specific kotlin-involved use case, or even the subproject bit… if i want to manage versions of transitive dependencies (i.e. via a platform). is there any strong reason to prefer adding it to each configuration manually, vs. using something like the below to apply it across all configurations. It seems like the very fact one is trying to manage transitives indicates that 99% of the time one would want them to be consistent across configurations
Copy code
configurations.configureEach { 
   add(it.name, platform(project(':my-platform')))
}
i.e. do:
Copy code
dependencies {
    configurations.configureEach {
        add(this.name, platform(libs.spring.boot.bom))
        add(this.name, platform(libs.fundamentals.bom))
        add(this.name, platform(libs.spring.cloud.bom) )
        add(this.name, platform(libs.spring.boot.admin.bom))
        add(this.name, platform(libs.spring.cloud.bom))
        add(this.name, platform(libs.resilience4j.bom))
    }
vs. say
Copy code
dependencies {
    annotationProcessor(platform(libs.spring.boot.bom))
    implementation(platform(libs.spring.boot.bom))
    runtimeOnly(platform(libs.spring.boot.bom))
    implementation(platform(libs.fundamentals.bom))
    runtimeOnly(platform(libs.fundamentals.bom))
    implementation(platform(libs.junit.bom))
    implementation(platform(libs.kotlin.bom))
    implementation(platform(libs.resilience4j.bom))
    implementation(platform(libs.spring.boot.admin.bom))
    implementation(platform(libs.spring.boot.bom))
    implementation(platform(libs.spring.cloud.bom))
}