Use BOMs in dependency management for JUnit and related libraries.

Description

Currently in the root POM we bring in the JUnit engine, which transitively brings in the JUnit API:

We also specify the version of this dependency under dependency management:

But some BOMs such as Spring Boot apparently reference the JUnit API dependency explicitly, so that importing it will override the transitive JUnit API from the root POM, resulting in version inconsistencies. This can show up as missing classes such as . Better to explicitly set the version of the the JUnit API dependency org.junit.jupiter:junit-jupiter-api in the root POM to ensure that the versions are consistent.

Environment

None

Activity

Show:

Garret Wilson July 29, 2023 at 11:28 PM

The SLF4J BOM still isn’t out yet, so I’ve moved that out to .

Garret Wilson July 27, 2023 at 12:37 PM

And just as important, should we bring back the JUnit et. al. version properties in case descendant classes need to easily override the whole shebang?

Having spring.boot.version is working so well for Spring, let’s bring back the version number properties for the other libraries as well, to allow descendant classes to easily upgrade (or downgrade!) to a different version without waiting for a new POM release. I don’t really like this sort of property in application classes, as it impedes the use of some goals of the Versions Maven Plugin (I think versions:use-releases for example), but in the root POM maybe this is less of an issue. In any case the ability to override the version in the descendant classes probably outweighs any minor inconveniences it causes, because the alternative leaves ancestor classes without an easy way to control versioning of things the root POM brings in.

Garret Wilson July 3, 2023 at 10:05 PM
Edited

While we’re in a holding pattern for the SLF4J BOM, I’m going to go ahead and add the Spring Boot BOM org.springframework.boot:spring-boot-dependencies, with slight reservation, to see how it works out. I guess since we’re already including the Spring Boot Maven Plugin dependency version, it won’t hurt much more to go ahead and indicate all Spring Boot versions of all its dependencies, and will be better than having mismatched versions.

This also means that now all projects that descend from the root POM will get the versions of Spring Boot “for free”. I’m not sure how I feel about that.

Update: Actually it’s not as simple as that. Apparently importing a BOM in dependency management doesn’t specify plugin versions for plugin management, so even importing the BOM, if I remove the version from the Spring Boot Maven Plugin, Maven says:

[WARNING] Some problems were encountered while building the effective model for com.globalmentor:globalmentor-root:pom:0.8.16-SNAPSHOT
[WARNING] 'build.plugins.plugin.version' for org.springframework.boot:spring-boot-maven-plugin is missing.

Maybe instead I should add a spring.boot.version property definition in the root POM, and only use it for the Spring Boot Maven Plugin. Then descendant projects can import the BOM using spring.boot.version, ensuring that they are using the same version as the plugin, and even update the spring.boot.version property to update the dependencies and plugin together.

Garret Wilson July 3, 2023 at 9:59 PM
Edited

Good news—it looks like SLF4J is going to get a BOM (see SLF4J-437). It seems to be scheduled for v2.0.8, so hopefully that will be released in time to include it for this ticket.

Garret Wilson June 16, 2023 at 12:19 AM

Consider whether we want to import the Spring BOM as well. We’re using Spring Boot Maven Plugin to create executable JARs, so we have to specify its version; this can cause version mismatches in descendant POMs even if they put Spring under dependency management, because for this artifact the ancestor POM will probably take priority. Still it seems like a drastic step just to use one plugin, when most project using the root POM will have no need of Spring in general. Maybe a more surgical approach would be to just introduce a spring.version property in the root POM. Then again importing the Spring BOM is simply setting a bunch of versions, and we have to download at least the Spring Boot Maven Plugin anyway, so there's probably not much overhead.

But wait, what about if the descendant POM needs to override the Spring version then? Wouldn't it still need to change the spring.version property? So maybe we need to use both techniques.

And just as important, should we bring back the JUnit et. al. version properties in case descendant classes need to easily override the whole shebang?

Fixed

Details

Assignee

Reporter

Components

Priority

Created January 27, 2023 at 5:09 PM
Updated July 31, 2023 at 10:07 PM
Resolved July 29, 2023 at 11:28 PM