How does gradle determine the version of a transitive dependency when using "integration platform(xxx.bom)"

hello, gradle experts,I have a gradle project which imports a BOM like below :
implementation platform("eu.europa.ec.joinup.sd-dss:dss-bom:${project.property("dssBomVersion")}")
And when I use the command “gradlew dependencyInsight” to check the version of one transtive dependency jaxb-runtime, I get the version of jaxb-runtime is upradeded from 2.3.9 to 4.0.4.

./gradlew project1:dependencyInsight --configuration=runtimeClasspath --dependency org.glassfish.jaxb:jaxb-runtime


> Task :project1:dependencyInsight
org.glassfish.jaxb:jaxb-runtime:4.0.4
  Variant runtime:
    | Attribute Name                 | Provided     | Requested    |
    |--------------------------------|--------------|--------------|
    | org.gradle.status              | release      |              |
    | org.gradle.category            | library      | library      |
    | org.gradle.libraryelements     | jar          | jar          |
    | org.gradle.usage               | java-runtime | java-runtime |
    | org.gradle.dependency.bundling |              | external     |
    | org.gradle.jvm.environment     |              | standard-jvm |
    | org.gradle.jvm.version         |              | 17           |
   Selection reasons:
      - Selected by rule
      - By constraint

org.glassfish.jaxb:jaxb-runtime:2.3.9 -> 4.0.4
+--- eu.europa.ec.joinup.sd-dss:dss-bom:5.13
|    \--- runtimeClasspath
+--- eu.europa.ec.joinup.sd-dss:dss-jaxb-common:5.13
|    +--- eu.europa.ec.joinup.sd-dss:dss-bom:5.13 (*)
|    +--- eu.europa.ec.joinup.sd-dss:specs-xmldsig:5.13
|    |    +--- eu.europa.ec.joinup.sd-dss:dss-bom:5.13 (*)
|    |    +--- eu.europa.ec.joinup.sd-dss:specs-validation-report:5.13
|    |    |    +--- eu.europa.ec.joinup.sd-dss:dss-bom:5.13 (*)
|    |    |    \--- eu.europa.ec.joinup.sd-dss:validation-policy:5.13
|    |    |         +--- eu.europa.ec.joinup.sd-dss:dss-bom:5.13 (*)
|    |    |         \--- eu.europa.ec.joinup.sd-dss:dss-document:5.13
|    |    |              +--- runtimeClasspath (requested eu.europa.ec.joinup.sd-dss:dss-document)
|    |    |              +--- eu.europa.ec.joinup.sd-dss:dss-bom:5.13 (*)
|    |    |              +--- eu.europa.ec.joinup.sd-dss:dss-cades:5.13
|    |    |              |    +--- eu.europa.ec.joinup.sd-dss:dss-bom:5.13 (*)
|    |    |              |    \--- eu.europa.ec.joinup.sd-dss:dss-pades:5.13
|    |    |              |         +--- runtimeClasspath (requested eu.europa.ec.joinup.sd-dss:dss-pades)
|    |    |              |         +--- eu.europa.ec.joinup.sd-dss:dss-bom:5.13 (*)
|    |    |              |         \--- eu.europa.ec.joinup.sd-dss:dss-pades-pdfbox:5.13
|    |    |              |              +--- runtimeClasspath (requested eu.europa.ec.joinup.sd-dss:dss-pades-pdfbox)
|    |    |              |              \--- eu.europa.ec.joinup.sd-dss:dss-bom:5.13 (*)
|    |    |              \--- eu.europa.ec.joinup.sd-dss:dss-xades:5.13
|    |    |                   +--- eu.europa.ec.joinup.sd-dss:dss-bom:5.13 (*)
|    |    |                   \--- eu.europa.ec.joinup.sd-dss:dss-tsl-validation:5.13
|    |    |                        +--- runtimeClasspath (requested eu.europa.ec.joinup.sd-dss:dss-tsl-validation)
|    |    |                        \--- eu.europa.ec.joinup.sd-dss:dss-bom:5.13 (*)
|    |    +--- eu.europa.ec.joinup.sd-dss:specs-trusted-list:5.13
|    |    |    +--- eu.europa.ec.joinup.sd-dss:dss-bom:5.13 (*)
|    |    |    +--- eu.europa.ec.joinup.sd-dss:dss-tsl-validation:5.13 (*)
|    |    |    \--- eu.europa.ec.joinup.sd-dss:specs-validation-report:5.13 (*)
|    |    \--- eu.europa.ec.joinup.sd-dss:specs-xades:5.13
|    |         +--- eu.europa.ec.joinup.sd-dss:dss-bom:5.13 (*)
|    |         +--- eu.europa.ec.joinup.sd-dss:specs-validation-report:5.13 (*)
|    |         \--- eu.europa.ec.joinup.sd-dss:specs-trusted-list:5.13 (*)
|    \--- eu.europa.ec.joinup.sd-dss:dss-jaxb-parsers:5.13
|         +--- eu.europa.ec.joinup.sd-dss:dss-bom:5.13 (*)
|         +--- eu.europa.ec.joinup.sd-dss:specs-validation-report:5.13 (*)
|         +--- eu.europa.ec.joinup.sd-dss:specs-trusted-list:5.13 (*)
|         +--- eu.europa.ec.joinup.sd-dss:specs-xades:5.13 (*)
|         +--- eu.europa.ec.joinup.sd-dss:dss-policy-jaxb:5.13
|         |    +--- eu.europa.ec.joinup.sd-dss:dss-bom:5.13 (*)
|         |    \--- eu.europa.ec.joinup.sd-dss:validation-policy:5.13 (*)
|         +--- eu.europa.ec.joinup.sd-dss:dss-diagnostic-jaxb:5.13
|         |    +--- eu.europa.ec.joinup.sd-dss:dss-bom:5.13 (*)
|         |    \--- eu.europa.ec.joinup.sd-dss:validation-policy:5.13 (*)
|         +--- eu.europa.ec.joinup.sd-dss:dss-simple-report-jaxb:5.13
|         |    +--- eu.europa.ec.joinup.sd-dss:dss-bom:5.13 (*)
|         |    \--- eu.europa.ec.joinup.sd-dss:validation-policy:5.13 (*)
|         +--- eu.europa.ec.joinup.sd-dss:dss-simple-certificate-report-jaxb:5.13
|         |    +--- eu.europa.ec.joinup.sd-dss:dss-bom:5.13 (*)
|         |    \--- eu.europa.ec.joinup.sd-dss:validation-policy:5.13 (*)
|         \--- eu.europa.ec.joinup.sd-dss:dss-detailed-report-jaxb:5.13
|              +--- eu.europa.ec.joinup.sd-dss:dss-bom:5.13 (*)
|              \--- eu.europa.ec.joinup.sd-dss:validation-policy:5.13 (*)
\--- eu.europa.ec.joinup.sd-dss:dss-jaxb-parsers:5.13 (*)

(*) - dependencies omitted (listed previously)

But When I checked the content of the BOM file, I didn’t see it specify the version of JAXB-runtime, neither 2.3.9 nor 4.0.4 see
https://repo1.maven.org/maven2/eu/europa/ec/joinup/sd-dss/dss-bom/5.13/dss-bom-5.13.pom,
And
https://repo1.maven.org/maven2/eu/europa/ec/joinup/sd-dss/dss-jaxb-common/5.13/dss-jaxb-common-5.13.pom

So Could you help me understand how gradle resolve the jaxb-runtime version should be upgraded to 4.0.4? Thank you.

Can you share a build --scan?

I just found that if I change the bom dependencies like below:

dependencyManagement {
    imports {
        mavenBom "eu.europa.ec.joinup.sd-dss:dss-bom:5.13"
    }
}

then run the same dependencyInsight commdn, I got the version of jaxb-runtime is 2.3.9:

org.glassfish.jaxb:jaxb-runtime:2.3.9 (selected by rule)
  Variant runtime:
    | Attribute Name                 | Provided     | Requested    |
    |--------------------------------|--------------|--------------|
    | org.gradle.status              | release      |              |
    | org.gradle.category            | library      | library      |
    | org.gradle.libraryelements     | jar          | jar          |
    | org.gradle.usage               | java-runtime | java-runtime |
    | org.gradle.dependency.bundling |              | external     |
    | org.gradle.jvm.environment     |              | standard-jvm |
    | org.gradle.jvm.version         |              | 17           |

org.glassfish.jaxb:jaxb-runtime:2.3.9
+--- eu.europa.ec.joinup.sd-dss:dss-jaxb-common:5.13
|    +--- eu.europa.ec.joinup.sd-dss:specs-xmldsig:5.13
|    |    +--- eu.europa.ec.joinup.sd-dss:specs-validation-report:5.13
|    |    |    \--- eu.europa.ec.joinup.sd-dss:validation-policy:5.13
|    |    |         \--- eu.europa.ec.joinup.sd-dss:dss-document:5.13
|    |    |              +--- runtimeClasspath (requested eu.europa.ec.joinup.sd-dss:dss-document)
|    |    |              +--- eu.europa.ec.joinup.sd-dss:dss-xades:5.13
|    |    |              |    \--- eu.europa.ec.joinup.sd-dss:dss-tsl-validation:5.13
|    |    |              |         \--- runtimeClasspath (requested eu.europa.ec.joinup.sd-dss:dss-tsl-validation)
|    |    |              \--- eu.europa.ec.joinup.sd-dss:dss-cades:5.13
|    |    |                   \--- eu.europa.ec.joinup.sd-dss:dss-pades:5.13
|    |    |                        +--- runtimeClasspath (requested eu.europa.ec.joinup.sd-dss:dss-pades)
|    |    |                        \--- eu.europa.ec.joinup.sd-dss:dss-pades-pdfbox:5.13
|    |    |                             \--- runtimeClasspath (requested eu.europa.ec.joinup.sd-dss:dss-pades-pdfbox)
|    |    +--- eu.europa.ec.joinup.sd-dss:specs-trusted-list:5.13
|    |    |    +--- eu.europa.ec.joinup.sd-dss:dss-tsl-validation:5.13 (*)
|    |    |    \--- eu.europa.ec.joinup.sd-dss:specs-validation-report:5.13 (*)
|    |    \--- eu.europa.ec.joinup.sd-dss:specs-xades:5.13
|    |         +--- eu.europa.ec.joinup.sd-dss:specs-validation-report:5.13 (*)
|    |         \--- eu.europa.ec.joinup.sd-dss:specs-trusted-list:5.13 (*)
|    \--- eu.europa.ec.joinup.sd-dss:dss-jaxb-parsers:5.13
|         +--- eu.europa.ec.joinup.sd-dss:specs-validation-report:5.13 (*)
|         +--- eu.europa.ec.joinup.sd-dss:specs-trusted-list:5.13 (*)
|         +--- eu.europa.ec.joinup.sd-dss:specs-xades:5.13 (*)
|         +--- eu.europa.ec.joinup.sd-dss:dss-detailed-report-jaxb:5.13
|         |    \--- eu.europa.ec.joinup.sd-dss:validation-policy:5.13 (*)
|         +--- eu.europa.ec.joinup.sd-dss:dss-simple-certificate-report-jaxb:5.13
|         |    \--- eu.europa.ec.joinup.sd-dss:validation-policy:5.13 (*)
|         +--- eu.europa.ec.joinup.sd-dss:dss-simple-report-jaxb:5.13
|         |    \--- eu.europa.ec.joinup.sd-dss:validation-policy:5.13 (*)
|         +--- eu.europa.ec.joinup.sd-dss:dss-diagnostic-jaxb:5.13
|         |    \--- eu.europa.ec.joinup.sd-dss:validation-policy:5.13 (*)
|         \--- eu.europa.ec.joinup.sd-dss:dss-policy-jaxb:5.13
|              \--- eu.europa.ec.joinup.sd-dss:validation-policy:5.13 (*)
\--- eu.europa.ec.joinup.sd-dss:dss-jaxb-parsers:5.13 (*)

(*) - dependencies omitted (listed previously)


It seems that different ways to specify BOM leads to the different transitive library versions.

You should remove the Spring Dependency Management plugin.
It it is an obsolete relict from times when Gradle did not have built-in BOM support, by now does more harm than good, and even its maintainer recommends not to use it anymore, but the built-in BOM support with platform(...).
That you use that plugin also explains strange versions, as it uses a sneaky big-hammer method to force versions that is not obvious from things like dependencies, dependencyInsight, or a build --scan.

Thanks, Vampire, you are right, I should not use “dependency Management plugin”. My last post just wants to point out that when I use “dependency management plugin”, It determines the version of jaxb-runtime is 2.3.9 which is expected. But if I use “implemenation platform(…)”, it determines the version of jaxb-runtime should be 4.0.4 which is actually not compatible with dss 5.13 modules. I created a simple helloworld spring gradle project which simply add a "implementation platform(“eu.europa.ec.joinup.sd-dss:dss-bom:5.13”), here is the link for its build scan.

I want to understand how gradle determine the jaxb-runtime version should be 4.0.4 since the bom pom file doesn’t specify it.

You do use that plugin.
You do not configure an explicit bom, but it uses the spring bom as the spring plugin is applied also.
As I said, remove / replace the plugin and you should be fine.

Could you show me how to modify it? Please forgive me if it’s a stupid question. I used to use Maven and is a newbie to the Gradle.

I use the official spring site (https://start.spring.io/) to generate the helloworld project. Below is the build.gradle generated by the site. Then I only add two lines related with “dss” into this gradle. And I use “implementation platform” to specify the BOM version for dss. Now the transtive dependnecy jaxb-runtime is 4.0.4. Could you show me how to modify it to make it to 2.3.9

plugins {
	id 'java'
	id 'org.springframework.boot' version '3.2.2'
	id 'io.spring.dependency-management' version '1.1.4'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'

java {
	sourceCompatibility = '17'
}

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-web'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'

	implementation platform("eu.europa.ec.joinup.sd-dss:dss-bom:5.13") <--- added by me
	implementation ('eu.europa.ec.joinup.sd-dss:dss-document') <--- added by me 

}

tasks.named('test') {
	useJUnitPlatform()
}

Remove that plugin from the plugins block and instead use the Spring BOM exactly like the other and as documented at Spring Boot Gradle Plugin Reference Guide.

Thanks for the link. It’s really useful. I update the build.gradle as below, but jaxb-runtime version is still resolved to be 4.0.4. Anything wrong?

plugins {
	id 'java'
	id 'org.springframework.boot' version '3.2.2'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'

java {
	sourceCompatibility = '17'
}

repositories {
	mavenCentral()
}

dependencies {
	implementation platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES)
	implementation 'org.springframework.boot:spring-boot-starter-web'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'

	implementation platform("eu.europa.ec.joinup.sd-dss:dss-bom:5.13")
	implementation ('eu.europa.ec.joinup.sd-dss:dss-document')

}

tasks.named('test') {
	useJUnitPlatform()
}

Not really.
As you can see from gw dependencyInsight --dependency org.glassfish.jaxb:jaxb-runtime --configuration runtimeClasspath or a build --scan, you can see that the Spring Boot BOM wants version 4.0.4, dss-bom wants version 2.3.9, and thus conflict resolution picks 4.0.4.
If you want to use 2.3.9 even though the Spring Boot BOM requests 4.0.4, you can for example use a strict version constraint to downgrade to 2.3.9 like:

dependencies {
    constraints {
        implementation("org.glassfish.jaxb:jaxb-runtime:2.3.9!!")
    }
}

yes, the output of “gradlew dependencies” is clear now why the version is 4.0.4 choosed after using the Gradle native BOM support. Thank you, Vampire.

1 Like