-
Notifications
You must be signed in to change notification settings - Fork 41.2k
Publish a Gradle version catalog for Spring Boot's own modules #29588
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Thanks for the suggestion, @jnizet. The main stumbling block that I encountered when looking at version catalogs in the past was that I don't think it's possible for a catalog to import a third-party bom or another catalog. Unless things have changed since I last looked, and looking at the API I can't see that they have, we'd have to stop using the boms of third-party libraries and instead manually declare each module in that library in our own catalog. That's possible of course, but it's quite a bit of extra work. We'd probably then need to write some validation tasks to ensure that our catalog covers everything that's in each third-party bom that we were using previously. That said, the dependency management plugin is also a non-zero amount of work. If it's going to live on, it really needs to be modernised (probably building on Gradle's constraints support) as the current codebase only uses APIs that were available in Gradle 2.x. It's testament to Gradle's backwards compatibility that it continues to work but we can't rely on that forever. I'll flag this one for discussion at a team meeting so that we can decide how best to spend our time in this area. |
Great, thanks @wilkinsona . |
I asked for BOM support but sadly the response was that this isn't going to happen. gradle/gradle#19142 |
Unfortunately, a version catalog isn't a useful replacement for the dependency management plugin for the same reasons that Gradle also has its own bom support with
Gradle's platform support offers 1 and version catalogs offer 2. Unfortunately, easily overriding the versions of transitive dependencies is not possible even if you use a platform and a version catalog in combination. With some regret, this means that we'll have to continue to maintain and recommend the use of the dependency management plugin. Our plan is to modernise it in time for Boot's 3.0 release towards the end of this year. We'll leave this issue open as a version catalog for Boot would still provide some benefits. For example, auto-completion for Boot's starters would be a nice developer experience improvement. It's a fairly small improvement, though, so we don't expect to tackle it any time soon. |
Maybe I'm missing something? |
For single-module libraries declaring a dependency is indeed quite concise. Things get considerably more verbose when the library has multiple modules. As an example, if you have a dependency on
Without the dependency management plugin you could declare individual dependencies but you'd have to know which dependencies to declare and what to exclude to retain the starter's behaviour. It might look something like this:
Another option would be to define some constraints for the three Tomcat modules or a resolution strategy to set their version but neither would be as concise or as declarative as setting the version property.
I don't think this is as simple as one way being correct and, therefore, others being incorrect. I think it's subjective and comes down to a team's personal preferences. We know that many Spring Boot users enjoy the concision and ease-of-use of the various starter modules and deliberately avoid direct dependencies on every module their code depends upon in favour of a single dependency that gives them everything they need. |
Agree, the real problem with your example is that the vendor does not provide a platform (BOM), otherwise it would boil down to a single dependency declaration again. It is very true that this situation is as it is in the majority of the JVM ecosystem. Some vendors even make it worse by publishing artifacts under the same name as others with different versioning schemes (looking at you Confluent). A good question for your example to the vendor would also be why it forces the annotations upon us, if clearly most users have no use for them (safe to say most if Spring excludes it).
We also heavily work with trusting transitives and using transitives to give us what we need. I really meant this in the context of the answer where I want to control a transitive dependency because my code requires a special version of it. In that case using the dependency extension of the plugin or declaring a dependency directly boils down to being exactly the same thing. We just have two different APIs in use. |
What if you crated a version catalog without versions for the dependencys you manage. Then you get type safety for the dependencies and versions managed by the platform/spring plugin? |
@hakonph sure, i imagine that's exactly what most people are doing. it would just be rather convenient if spring itself provided the catalog, so thousands of developers didn't have to do the duplicative work of defining the catalog entries for all the various spring projects - when it could be done once upstream and imported. Not a major need, but it's a nice little "Quality of Life" improvement. |
I second the idea of @hakonph . If Spring-Boot ever releases a version catalog, all dependencies should be defined without their versions, except the entries for the dependencies {
implementation(enforcedPlatform(springBootLibs.bom))
implementation(springBootLibs.starter.web) I also think the version catalog should not duplicate the complete Spring-Boot-BOM. It should only contain the libraries of the That being said: Micronaut auto-generates its version catalog by converting their BOM. I would be fine with that, too. |
This would be nice! |
I also had asked the Gradle team about BOM support in gradle/gradle#26048 and they rejected my idea as well...so I am working on a settings plugin austinarbor/version-catalog-generator which automatically generates the version catalog based on a dependency in your It's still in alpha so it's a little rough around the edges and could use more customization options, but it generally seems to be working pretty well already. The API is better in the Kotlin DSL but I am trying to think of how to improve the Groovy DSL. I think the biggest missing piece is easily forcing a different version (like the Sorry for the self-promo but I stumbled upon this issue and thought the plugin I am working on could be of use here. If it's against the rules I will remove this comment. If anyone finds the plugin useful or can think of how to make it work better for the use cases described in here I will happily hear your feedback! |
Thanks for sharing, @austinarbor. Your comment is absolutely fine. Good luck with the project. |
A version catalog (or settings plugin) would also help with managing the versions of third-party plugins, keeping them up-to-date and/or aligned with other dependencies from the same project. I've opened #37836. |
Playing around with some ideas.
Also experimenting with using the same configuration data in the spring-boot-dependencies build, but ran into issues that I still need to resolve. Any feedback on either approach welcome. |
I'll say this, I personally don't want/need this as a replacement for a BOM, I just don't want to write the dependencies out one at a time to get the static accessors. I'd be plenty happy if spring generated a flat version of a "libs.versions.toml" file that I had to get from the repo, that had no versions defined in it. |
That is what my experiments are doing. I added support to the spring boot build to publish a catalog toml file along with the other publications. In your settings.gradle you register a new catalog based on that dependency (I called it Excerpt of the published catalog:
The BOM is not being replaced, my example pulls its definition from the above published catalog.
The idea of a |
As a user, I think a catalog without the versions diminishes the value. The original intent of version catalogs is to align versions between modules. With projects like spring and micronaut, I think it then becomes more desirable to use a version catalog in a single-module project so you can use typed dependencies without the manual effort of declaring them one-by-one yourself. However, introducing a catalog without the versions would then break the original intent of the version catalog. If I have a multi-module project, one with spring and one without, but I want to use the same dependency versions as the spring module in my non-spring module, the catalog without versions won't help me do that. I would need to add spring as a dependency to make it work...which I think defeats the original purpose? As I mentioned above, you can use my settings plugin here to use any BOM as a version catalog (including the versions, and the ability to override any version). I am definitely in support of a spring-native solution, but I think anything besides a fully declared catalog including all versions etc would fall short of expectations. |
If I was now working on what I did back in Nov, I would agree with you and put the versions in the catalog. However, even with a no-ver-catalog, the non-spring modules could still apply the spring bom/platform to resolve the same versions (I'll note that my catalog has a version for the spring boot bom that matches the catalog version).
I was mostly focusing on how to fit the catalog build into the spring boot build, I left it up for debate as to whether the catalog should include all spring boot deps or just the published spring boot modules. My first branch was one that tried to tie the catalog creation into the existing bom build, allowing the spring maintainers to control what goes into the catalog or not. I remember I ran into an issue causing me to create my second branch/POC, but I cannot recall what the issue was and would have to open it up again. I was hoping to get feedback from the maintainers before I invest further effort towards making a PR. In general, I'm on the same page as you @austinarbor. Also, nice plugin! |
@wilkinsona any chance I can get the location of that code generating that part of the asciidoc that I asked for in #37836 anyways? |
It's |
I read this through but I did not get what is blocking a public version catalog. I understand that it's not possible to include third-party BOMs, but it should be doable to publish a version catalog for Spring own modules. |
from what I can tell it's because @wilkinsona thinks that a version catalog only exists to replace a bill of materials; when a version catalog can provide no versions. I simply delayed in working on this; but that'll be a 3rd party project once I do. |
I am aware that it doesn't have to provide versions. It's hard not to be given that it has been discussed in this very issue where other members of the community have been both for and against such a version catalog.
There's nothing specifically blocking this issue (otherwise it would be labelled as blocked) but we need to do some design work to decide exactly what we want to do (there's no clear consensus in this issue) and then prioritise doing it. We have quite a lot of other things on ours plates at the moment so it's unlikely that this will make it to the top of the priority list soon. |
Gradle now supports version catalogs, which have the advantage of generating type-safe accessors to reference the dependencies, allowing, for example
with support for auto-completion.
Such version catalogs can be defined in the build itself, but can also be published and then consumed by other projects. Micronaut for example does that, allowing to do in the settings files
and then in the build files
Overriding versions from the imported catalog is supported too.
Publishing such a version catalog along with the Spring Boot BOM would be a nice feature, which would allow migrating away from the spring dependencies plugin, now that gradle seems to support its features (with version catalogs and with the platform plugin), and benefit from the additional advantage of type-safe accessors for dependencies.
The text was updated successfully, but these errors were encountered: