-
-
Notifications
You must be signed in to change notification settings - Fork 969
Solve BOM existential crisis - Fixes #15258 #15259
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
base: 7.1.x
Are you sure you want to change the base?
Conversation
grails-bom/build.gradle
Outdated
|
|
||
| // Disable Gradle Module Metadata (.module files) for the BOM | ||
| // This allows properties to be overridden with the Spring dependency management plugin | ||
| tasks.withType(GenerateModuleMetadata).configureEach { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This cannot be done. We switched to the modules intentionally to fix gradle resolution without the dependency management plugin. The intent is to remove the dependency management plugin in grails 8
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jdaugherty modules break the dependency management plugin. It doesn't work AND all this is doing is turning off a useless module for the bom ONLY. Why do you want a gradle module for a bom??
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because we're ultimately adopting the platform() in Grails 8 and that requires the gradle module. It sounds like you're using both platform() and spring dependency management plugin. This is the cause of your issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jdaugherty, not I am not using platform at all. It is completely broken as is.
| */ | ||
| class PropertyNameCalculator { | ||
|
|
||
| static final String GRAILS_VERSION_PROPERTY = 'grails.version' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why would you ever override different versions of grails projects? Why not just change the version of the bom you're using instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jdaugherty Compare the before (M3) and after BOMs.
I am saying overriding is better than using a grails property for everyone because if you did that you would get version conflicts from transitive dependencies.
I am recommending using
<grails.version>7.1.0-SNAPSHOT</grails.version>instead of
<grails.async.version>7.1.0-SNAPSHOT</grails.async.version>
<grails.async.core.version>7.1.0-SNAPSHOT</grails.async.core.version>
<grails.async.gpars.version>7.1.0-SNAPSHOT</grails.async.gpars.version>
<grails.async.rxjava.version>7.1.0-SNAPSHOT</grails.async.rxjava.version>
<grails.async.rxjava2.version>7.1.0-SNAPSHOT</grails.async.rxjava2.version>
<grails.async.rxjava3.version>7.1.0-SNAPSHOT</grails.async.rxjava3.version>
<grails.bootstrap.version>7.1.0-SNAPSHOT</grails.bootstrap.version>
<grails.cache.version>7.1.0-SNAPSHOT</grails.cache.version>
<grails.codecs.version>7.1.0-SNAPSHOT</grails.codecs.version>
<grails.codecs.core.version>7.1.0-SNAPSHOT</grails.codecs.core.version>
<grails.common.version>7.1.0-SNAPSHOT</grails.common.version>
<grails.console.version>7.1.0-SNAPSHOT</grails.console.version>
<grails.controllers.version>7.1.0-SNAPSHOT</grails.controllers.version>
<grails.converters.version>7.1.0-SNAPSHOT</grails.converters.version>
<grails.core.version>7.1.0-SNAPSHOT</grails.core.version>
<grails.data.hibernate5.version>7.1.0-SNAPSHOT</grails.data.hibernate5.version>
<grails.data.hibernate5.core.version>7.1.0-SNAPSHOT</grails.data.hibernate5.core.version>
<grails.data.hibernate5.dbmigration.version>7.1.0-SNAPSHOT</grails.data.hibernate5.dbmigration.version>
<grails.data.hibernate5.spring.boot.version>7.1.0-SNAPSHOT</grails.data.hibernate5.spring.boot.version>
<grails.data.mongodb.version>7.1.0-SNAPSHOT</grails.data.mongodb.version>
<grails.data.mongodb.bson.version>7.1.0-SNAPSHOT</grails.data.mongodb.bson.version>
<grails.data.mongodb.core.version>7.1.0-SNAPSHOT</grails.data.mongodb.core.version>
<grails.data.mongodb.ext.version>7.1.0-SNAPSHOT</grails.data.mongodb.ext.version>
<grails.data.mongodb.gson.templates.version>7.1.0-SNAPSHOT</grails.data.mongodb.gson.templates.version>
<grails.data.mongodb.spring.boot.version>7.1.0-SNAPSHOT</grails.data.mongodb.spring.boot.version>
<grails.data.simple.version>7.1.0-SNAPSHOT</grails.data.simple.version>
<grails.databinding.version>7.1.0-SNAPSHOT</grails.databinding.version>
<grails.databinding.core.version>7.1.0-SNAPSHOT</grails.databinding.core.version>
<grails.datamapping.async.version>7.1.0-SNAPSHOT</grails.datamapping.async.version>
<grails.datamapping.core.version>7.1.0-SNAPSHOT</grails.datamapping.core.version>
<grails.datamapping.core.test.version>7.1.0-SNAPSHOT</grails.datamapping.core.test.version>
<grails.datamapping.support.version>7.1.0-SNAPSHOT</grails.datamapping.support.version>
<grails.datamapping.tck.version>7.1.0-SNAPSHOT</grails.datamapping.tck.version>
<grails.datamapping.validation.version>7.1.0-SNAPSHOT</grails.datamapping.validation.version>
<grails.datasource.version>7.1.0-SNAPSHOT</grails.datasource.version>
<grails.datastore.async.version>7.1.0-SNAPSHOT</grails.datastore.async.version>
<grails.datastore.core.version>7.1.0-SNAPSHOT</grails.datastore.core.version>
<grails.datastore.web.version>7.1.0-SNAPSHOT</grails.datastore.web.version>
<grails.dependencies.assets.version>7.1.0-SNAPSHOT</grails.dependencies.assets.version>
<grails.dependencies.starter.web.version>7.1.0-SNAPSHOT</grails.dependencies.starter.web.version>
<grails.dependencies.test.version>7.1.0-SNAPSHOT</grails.dependencies.test.version>
<grails.domain.class.version>7.1.0-SNAPSHOT</grails.domain.class.version>
<grails.encoder.version>7.1.0-SNAPSHOT</grails.encoder.version>
<grails.events.version>7.1.0-SNAPSHOT</grails.events.version>
<grails.events.compat.version>7.1.0-SNAPSHOT</grails.events.compat.version>
<grails.events.core.version>7.1.0-SNAPSHOT</grails.events.core.version>
<grails.events.gpars.version>7.1.0-SNAPSHOT</grails.events.gpars.version>
<grails.events.rxjava.version>7.1.0-SNAPSHOT</grails.events.rxjava.version>
<grails.events.rxjava2.version>7.1.0-SNAPSHOT</grails.events.rxjava2.version>
<grails.events.rxjava3.version>7.1.0-SNAPSHOT</grails.events.rxjava3.version>
<grails.events.spring.version>7.1.0-SNAPSHOT</grails.events.spring.version>
<grails.events.transforms.version>7.1.0-SNAPSHOT</grails.events.transforms.version>
<grails.fields.version>7.1.0-SNAPSHOT</grails.fields.version>
<grails.geb.version>7.1.0-SNAPSHOT</grails.geb.version>
<grails.gsp.version>7.1.0-SNAPSHOT</grails.gsp.version>
<grails.gsp.core.version>7.1.0-SNAPSHOT</grails.gsp.core.version>
<grails.gsp.spring.boot.version>7.1.0-SNAPSHOT</grails.gsp.spring.boot.version>
<grails.i18n.version>7.1.0-SNAPSHOT</grails.i18n.version>
<grails.interceptors.version>7.1.0-SNAPSHOT</grails.interceptors.version>
<grails.layout.version>7.1.0-SNAPSHOT</grails.layout.version>
<grails.logging.version>7.1.0-SNAPSHOT</grails.logging.version>
<grails.micronaut.version>7.1.0-SNAPSHOT</grails.micronaut.version>
<grails.mimetypes.version>7.1.0-SNAPSHOT</grails.mimetypes.version>
<base.version>7.1.0-SNAPSHOT</base.version>
<plugin.version>7.1.0-SNAPSHOT</plugin.version>
<profile.version>7.1.0-SNAPSHOT</profile.version>
<rest.api.version>7.1.0-SNAPSHOT</rest.api.version>
<rest.api.plugin.version>7.1.0-SNAPSHOT</rest.api.plugin.version>
<web.version>7.1.0-SNAPSHOT</web.version>
<web.plugin.version>7.1.0-SNAPSHOT</web.plugin.version>
<grails.rest.transforms.version>7.1.0-SNAPSHOT</grails.rest.transforms.version>
<grails.scaffolding.version>7.1.0-SNAPSHOT</grails.scaffolding.version>
<grails.services.version>7.1.0-SNAPSHOT</grails.services.version>
<grails.shell.cli.version>7.1.0-SNAPSHOT</grails.shell.cli.version>
<grails.sitemesh3.version>7.1.0-SNAPSHOT</grails.sitemesh3.version>
<grails.spring.version>7.1.0-SNAPSHOT</grails.spring.version>
<grails.taglib.version>7.1.0-SNAPSHOT</grails.taglib.version>
<grails.test.core.version>7.1.0-SNAPSHOT</grails.test.core.version>
<grails.testing.support.core.version>7.1.0-SNAPSHOT</grails.testing.support.core.version>
<grails.testing.support.datamapping.version>7.1.0-SNAPSHOT</grails.testing.support.datamapping.version>
<grails.testing.support.mongodb.version>7.1.0-SNAPSHOT</grails.testing.support.mongodb.version>
<grails.testing.support.views.gson.version>7.1.0-SNAPSHOT</grails.testing.support.views.gson.version>
<grails.testing.support.web.version>7.1.0-SNAPSHOT</grails.testing.support.web.version>
<grails.url.mappings.version>7.1.0-SNAPSHOT</grails.url.mappings.version>
<grails.validation.version>7.1.0-SNAPSHOT</grails.validation.version>
<grails.views.core.version>7.1.0-SNAPSHOT</grails.views.core.version>
<grails.views.gson.version>7.1.0-SNAPSHOT</grails.views.gson.version>
<grails.views.markup.version>7.1.0-SNAPSHOT</grails.views.markup.version>
<grails.web.boot.version>7.1.0-SNAPSHOT</grails.web.boot.version>
<grails.web.common.version>7.1.0-SNAPSHOT</grails.web.common.version>
<grails.web.core.version>7.1.0-SNAPSHOT</grails.web.core.version>
<grails.web.databinding.version>7.1.0-SNAPSHOT</grails.web.databinding.version>
<grails.web.gsp.version>7.1.0-SNAPSHOT</grails.web.gsp.version>
<grails.web.gsp.taglib.version>7.1.0-SNAPSHOT</grails.web.gsp.taglib.version>
<grails.web.jsp.version>7.1.0-SNAPSHOT</grails.web.jsp.version>
<grails.web.mvc.version>7.1.0-SNAPSHOT</grails.web.mvc.version>
<grails.web.taglib.version>7.1.0-SNAPSHOT</grails.web.taglib.version>
<grails.web.url.mappings.version>7.1.0-SNAPSHOT</grails.web.url.mappings.version>
<grails.gradle.plugins.version>7.1.0-SNAPSHOT</grails.gradle.plugins.version>
<grails.gradle.model.version>7.1.0-SNAPSHOT</grails.gradle.model.version>
<grails.gradle.common.version>7.1.0-SNAPSHOT</grails.gradle.common.version>
<grails.gradle.tasks.version>7.1.0-SNAPSHOT</grails.gradle.tasks.version>
...|
As an incremental fix, we should first merge: #15260 which requires apache/grails-gradle-publish#16 Not having a deferred lookup is the main reason properties were broken in the bom. |
This still
|
|
After publishing the other changes, the bom with properties can be seen here: https://repository.apache.org/service/local/repo_groups/snapshots-group/content/org/apache/grails/grails-bom/7.0.4-SNAPSHOT/grails-bom-7.0.4-20251126.132828-4.pom Concerning this comment: Number 2 is false. The spring dependency management plugin works just fine with the module metadata published. You can see this in the example project here: https://github.com/jdaugherty/grails-bom-demo-spring-dependency-management (this project downgrades spring boot with a property setting only). Again, you must not use the platform if you want the property behavior. We intentionally shipped the platform() because there isn't an alternative in gradle build script & to be consistent we defined it in both locations. We intend to remove the spring dependency management plugin in Grails 8. For sorting versions, I'm indifferent and I think it's ok to accept. For the 131 redundant versions, by redundant I assume you mean that a grails.version property isn't defined for the grails project? Technically if you know what you're doing, you could selectively upgrade one of those libraries with the way this is defined. This allows for the most flexibility. I think this is something that should be discussed since we launched 7.0.0 with this design. If you want to change the overall grails version, you would just select a different bom version. The current state allows for the most flexibility. |
|
@codeconsole I changed the example project to make it clear that i removed platform() - the initial commit now contains the default app generated in grails forge and the second contains the way you would setup your project to use the dependency management plugin. |
@jdaugherty you are right, I was able to get RC2 working. I think the big error there was
|
@jdaugherty The emphasis here is I don't see a working scenario where you would want to set any of those versions via a property because their transitive dependencies would resolve a different version. Since they are all based off a Grails version, setting to a different version would cause unexpected transitive resolution. |
The original goal of the bom changes was so we could document it & define dependencies in a central place - especially because we generate two boms (grails-gradle-bom & grails-bom). I used a prefix naming strategy originally because it was claimed that dependabot could handle versions & coordinates in the same gradle file - so I wanted to keep it simple for dependabot. What that did not mention is it only handles String versions & can't handle the map syntax. So we can rework this ... For Gradle 9, we have to rewrite all of it anyhow - gradle doesn't allow across project resolution as of Gradle 9 (see the versions plugin & associated ticket where this was discovered without a release note in Gradle 9). We need to extract the bom logic into it's own plugin using maven specific libraries to parse poms instead of gradle - similar to what spring did and then generate documentation & the bom from that plugin. We can hack in the old name if you want, but the current property is based on the coordinate name. As for it working with both, that's great news. We should revert the metadata disable then. |
Isn't that only true if the transitive dependency is in the bom? What if someone wanted to pull in fields because a new default template was added - then that dependency doesn't matter. I could see this be true for a lot of grails projects. |
|
We discussed this PR in the weekly meeting. Given that the multiple properties allow for the option to customize select libraries, we want to keep that feature. I believe the only other feature this PR contributed was sorting the properties. If you want to update the PR for that we can merge this. Otherwise, we'll plan on closing this one. |
@jdaugherty can you give an actual use case where you would use these properties? There is no grouping on any of them which makes no difference if you import them directly. <grails.async.gpars.version>7.1.0-SNAPSHOT</grails.async.gpars.version>
<grails.events.gpars.version>7.1.0-SNAPSHOT</grails.events.gpars.version>why would you set grails.async.gpars.version=7.1.0-SNAPSHOTinstead of just putting it in the I could, possibly, understand The decision to keep 130 properties sounds like it is going to introduce a lot of unknown behavior by the end user. |
|
The reason we kept the dependency management plugin is it uses properties to be able to quickly set versions. There's a version for each project because each project is a separate jar. The only reason they're the same version is because of the mono repo, but technically people can choose different versions. There also isn't "unknown" behavior by leaving properties in a pom. We're opting to keep the properties to keep the flexibility of prior grails versions. |
|
@codeconsole I haven't seen an example of where it's bad to keep the flexibility of the pom properties. I also haven't seen any updates to this PR. do you wish to abandon it? |
I am finding it quite hard to understand why you would ever set a version for an individual dependency instead of a group? With my previous bom code, versions were set on groups, which did have value. As I asked previously: what is the advantage of grails.async.gpars.version=7.1.0-SNAPSHOTover implementation 'org.apache.grails.asyncs:grails-async-gpars:7.1.0-SNAPSHOT'why would you ever do the former?? |
|
If the property is the same for all Grails modules, couldn't you just use the |
|
@codeconsole To answer your question: the advantage of the property approach is you can define properties in more ways independently of the project. This is the only reason we kept the dependency management plugin. As long as we keep that plugin, we should keep the property support since it's central to including that plugin. |
|
Also, as for why someone would want to upgrade, I have given previous examples of that - fields or more isolated downstream projects could very well be updated instead of something like grails-core. So the property support + arbitrary upgrades is a valid use case. |
|
@jdaugherty I am still not understanding your explanation for these 130 properties that all have the same version Properties in boms are typically for dependency groups, not individual child dependencies of a project.
|
you could, but them you would get that version's bom dependencies. I would argue more for removing the 100+ module properties altogether. I think the bom now is overwhelmed with so many redundant properties. I'd recommend any of the following:
|
|
It's not about which of these is better. Since Grails 7 applications are still generated with the Spring Dependency Management Grails Plugin, we support both pathways to override the grails artifact versions. In addition to just using the new grails-bom version, which 99.999% of user will do. Overriding just one or a few of these artifacts will rarely be done, but we must maintain support for it via
Users can pick which path they want to follow and having both is consistent with prior Grails versions. Removing the For Grails 8, #14142 will be addressed. |
This isn't a question of better. It's about proper bom design and using bom versions how they are intended. Versions are more there to specify versions for dependency groups, not individual submodules. There is no history of these 100+ versions existing. Why introduce them now? It's variable overkill. This looks more like a bug than a feature. The correct approach would either be: 1. remove them completely or 2. create the appropriate groups (which is how historically it was done). Please explain what the expected behavior is in it's current design for: will this also update grails async or just Is this introduction of a 130 individual versions documented anywhere with usage instructions? |
|
@codeconsole You're not presenting a technical argument here. We answered your questions:
I'm a -1 on this PR / code change until a technical reason can be given on why we should limit end apps flexibility & choice. |
|
@jdaugherty The 130 versions doesn't have anything to do with the mono-repo. It has to do with, all of the sudden, introducing variables for versions specific to the project. There should never be a 1-1 correlation between dependencies and version variables. Can you give an example of anyone else that does this?? project submodules versions should be hard coded This is how things worked previously. Have you looked at the Spring Boot Bom? What I am suggesting models exactly what Spring Boot does and was how everything worked before. For example, if Spring were to follow your suggestion, they would need to introduce 100's of versions as well: ...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-resttestclient</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-rsocket</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-rsocket-test</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-security</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-security-oauth2-authorization-server</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-security-oauth2-client</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-security-oauth2-resource-server</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-security-saml2</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-security-test</artifactId>
<version>4.0.1</version>
</dependency>
...If Spring did what you were suggesting, they would have to add versions to their bom for: spring-boot,spring-boot-activemq,spring-boot-actuator,spring-boot-actuator-autoconfigure,spring-boot-amqp,spring-boot-artemis,spring-boot-autoconfigure,spring-boot-autoconfigure-classic,spring-boot-autoconfigure-classic-modules,spring-boot-autoconfigure-processor,spring-boot-batch,spring-boot-batch-jdbc,spring-boot-buildpack-platform,spring-boot-cache,spring-boot-cache-test,spring-boot-cassandra,spring-boot-cloudfoundry,spring-boot-configuration-metadata,spring-boot-configuration-processor,spring-boot-couchbase,spring-boot-data-cassandra,spring-boot-data-cassandra-test,spring-boot-data-commons,spring-boot-data-couchbase,spring-boot-data-couchbase-test,spring-boot-data-elasticsearch,spring-boot-data-elasticsearch-test,spring-boot-data-jdbc,spring-boot-data-jdbc-test,spring-boot-data-jpa,spring-boot-data-jpa-test,spring-boot-data-ldap,spring-boot-data-ldap-test,spring-boot-data-mongodb,spring-boot-data-mongodb-test,spring-boot-data-neo4j,spring-boot-data-neo4j-test,spring-boot-data-r2dbc,spring-boot-data-r2dbc-test,spring-boot-data-redis,spring-boot-data-redis-test,spring-boot-data-rest,spring-boot-devtools,spring-boot-docker-compose,spring-boot-elasticsearch,spring-boot-flyway,spring-boot-freemarker,spring-boot-graphql,spring-boot-graphql-test,spring-boot-groovy-templates,spring-boot-gson,spring-boot-h2console,spring-boot-hateoas,spring-boot-hazelcast,spring-boot-health,spring-boot-hibernate,spring-boot-http-client,spring-boot-http-codec,spring-boot-http-converter,spring-boot-integration,spring-boot-jackson,spring-boot-jackson2,spring-boot-jarmode-tools,spring-boot-jdbc,spring-boot-jdbc-test,spring-boot-jersey,spring-boot-jetty,spring-boot-jms,spring-boot-jooq,spring-boot-jooq-test,spring-boot-jpa,spring-boot-jpa-test,spring-boot-jsonb,spring-boot-kafka,spring-boot-kotlinx-serialization-json,spring-boot-ldap,spring-boot-liquibase,spring-boot-loader,spring-boot-mail,spring-boot-micrometer-metrics,spring-boot-micrometer-metrics-test,spring-boot-micrometer-observation,spring-boot-micrometer-tracing,spring-boot-micrometer-tracing-brave,spring-boot-micrometer-tracing-opentelemetry,spring-boot-micrometer-tracing-test,spring-boot-mongodb,spring-boot-mustache,spring-boot-neo4j,spring-boot-netty,spring-boot-opentelemetry,spring-boot-persistence,spring-boot-properties-migrator,spring-boot-pulsar,spring-boot-quartz,spring-boot-r2dbc,spring-boot-reactor,spring-boot-reactor-netty,spring-boot-restclient,spring-boot-restclient-test,spring-boot-restdocs,spring-boot-resttestclient,spring-boot-rsocket,spring-boot-rsocket-test,spring-boot-security,spring-boot-security-oauth2-authorization-server,spring-boot-security-oauth2-client,spring-boot-security-oauth2-resource-server,spring-boot-security-saml2,spring-boot-security-test,spring-boot-sendgrid,spring-boot-servlet,spring-boot-session,spring-boot-session-data-redis,spring-boot-session-jdbc,spring-boot-sql,spring-boot-starter,spring-boot-starter-activemq,spring-boot-starter-activemq-test,spring-boot-starter-actuator,spring-boot-starter-actuator-test,spring-boot-starter-amqp,spring-boot-starter-amqp-test,spring-boot-starter-artemis,spring-boot-starter-artemis-test,spring-boot-starter-aspectj,spring-boot-starter-aspectj-test,spring-boot-starter-batch,spring-boot-starter-batch-jdbc,spring-boot-starter-batch-jdbc-test,spring-boot-starter-batch-test,spring-boot-starter-cache,spring-boot-starter-cache-test,spring-boot-starter-cassandra,spring-boot-starter-cassandra-test,spring-boot-starter-classic,spring-boot-starter-cloudfoundry,spring-boot-starter-cloudfoundry-test,spring-boot-starter-couchbase,spring-boot-starter-couchbase-test,spring-boot-starter-data-cassandra,spring-boot-starter-data-cassandra-test,spring-boot-starter-data-cassandra-reactive,spring-boot-starter-data-cassandra-reactive-test,spring-boot-starter-data-couchbase,spring-boot-starter-data-couchbase-test,spring-boot-starter-data-couchbase-reactive,spring-boot-starter-data-couchbase-reactive-test,spring-boot-starter-data-elasticsearch,spring-boot-starter-data-elasticsearch-test,spring-boot-starter-data-jdbc,spring-boot-starter-data-jdbc-test,spring-boot-starter-data-jpa,spring-boot-starter-data-jpa-test,spring-boot-starter-data-ldap,spring-boot-starter-data-ldap-test,spring-boot-starter-data-mongodb,spring-boot-starter-data-mongodb-test,spring-boot-starter-data-mongodb-reactive,spring-boot-starter-data-mongodb-reactive-test,spring-boot-starter-data-neo4j,spring-boot-starter-data-neo4j-test,spring-boot-starter-data-r2dbc,spring-boot-starter-data-r2dbc-test,spring-boot-starter-data-redis,spring-boot-starter-data-redis-test,spring-boot-starter-data-redis-reactive,spring-boot-starter-data-redis-reactive-test,spring-boot-starter-data-rest,spring-boot-starter-data-rest-test,spring-boot-starter-elasticsearch,spring-boot-starter-elasticsearch-test,spring-boot-starter-flyway,spring-boot-starter-flyway-test,spring-boot-starter-freemarker,spring-boot-starter-freemarker-test,spring-boot-starter-graphql,spring-boot-starter-graphql-test,spring-boot-starter-groovy-templates,spring-boot-starter-groovy-templates-test,spring-boot-starter-gson,spring-boot-starter-gson-test,spring-boot-starter-hateoas,spring-boot-starter-hateoas-test,spring-boot-starter-hazelcast,spring-boot-starter-hazelcast-test,spring-boot-starter-integration,spring-boot-starter-integration-test,spring-boot-starter-jackson,spring-boot-starter-jackson-test,spring-boot-starter-jdbc,spring-boot-starter-jdbc-test,spring-boot-starter-jersey,spring-boot-starter-jersey-test,spring-boot-starter-jetty,spring-boot-starter-jetty-runtime,spring-boot-starter-jms,spring-boot-starter-jms-test,spring-boot-starter-jooq,spring-boot-starter-jooq-test,spring-boot-starter-json,spring-boot-starter-jsonb,spring-boot-starter-jsonb-test,spring-boot-starter-kafka,spring-boot-starter-kafka-test,spring-boot-starter-kotlinx-serialization-json,spring-boot-starter-kotlinx-serialization-json-test,spring-boot-starter-ldap,spring-boot-starter-ldap-test,spring-boot-starter-liquibase,spring-boot-starter-liquibase-test,spring-boot-starter-log4j2,spring-boot-starter-logback,spring-boot-starter-logging,spring-boot-starter-mail,spring-boot-starter-mail-test,spring-boot-starter-micrometer-metrics,spring-boot-starter-micrometer-metrics-test,spring-boot-starter-mongodb,spring-boot-starter-mongodb-test,spring-boot-starter-mustache,spring-boot-starter-mustache-test,spring-boot-starter-neo4j,spring-boot-starter-neo4j-test,spring-boot-starter-oauth2-authorization-server,spring-boot-starter-oauth2-client,spring-boot-starter-oauth2-resource-server,spring-boot-starter-opentelemetry,spring-boot-starter-opentelemetry-test,spring-boot-starter-pulsar,spring-boot-starter-pulsar-test,spring-boot-starter-quartz,spring-boot-starter-quartz-test,spring-boot-starter-r2dbc,spring-boot-starter-r2dbc-test,spring-boot-starter-reactor-netty,spring-boot-starter-restclient,spring-boot-starter-restclient-test,spring-boot-starter-rsocket,spring-boot-starter-rsocket-test,spring-boot-starter-security,spring-boot-starter-security-test,spring-boot-starter-security-oauth2-authorization-server,spring-boot-starter-security-oauth2-authorization-server-test,spring-boot-starter-security-oauth2-client,spring-boot-starter-security-oauth2-client-test,spring-boot-starter-security-oauth2-resource-server,spring-boot-starter-security-oauth2-resource-server-test,spring-boot-starter-security-saml2,spring-boot-starter-security-saml2-test,spring-boot-starter-sendgrid,spring-boot-starter-sendgrid-test,spring-boot-starter-session-data-redis,spring-boot-starter-session-data-redis-test,spring-boot-starter-session-jdbc,spring-boot-starter-session-jdbc-test,spring-boot-starter-test,spring-boot-starter-test-classic,spring-boot-starter-thymeleaf,spring-boot-starter-thymeleaf-test,spring-boot-starter-tomcat,spring-boot-starter-tomcat-runtime,spring-boot-starter-validation,spring-boot-starter-validation-test,spring-boot-starter-web,spring-boot-starter-web-services,spring-boot-starter-webclient,spring-boot-starter-webclient-test,spring-boot-starter-webflux,spring-boot-starter-webflux-test,spring-boot-starter-webmvc,spring-boot-starter-webmvc-test,spring-boot-starter-webservices,spring-boot-starter-webservices-test,spring-boot-starter-websocket,spring-boot-starter-websocket-test,spring-boot-starter-zipkin,spring-boot-test,spring-boot-test-autoconfigure,spring-boot-test-classic-modules,spring-boot-testcontainers,spring-boot-thymeleaf,spring-boot-tomcat,spring-boot-transaction,spring-boot-validation,spring-boot-web-server,spring-boot-webclient,spring-boot-webclient-test,spring-boot-webflux,spring-boot-webflux-test,spring-boot-webmvc,spring-boot-webmvc-test,spring-boot-webservices,spring-boot-webservices-test,spring-boot-websocket,spring-boot-webtestclient,spring-boot-zipkin,spring-boot-starter-zipkin-test but they didn't. Why is that? Are you saying what Spring Boot is doing "limit end apps flexibility & choice"? |
To bom or not to bom?
This fix allows me to go to sleep tonight...
#15258
Gradle modules are not needed for the bom and prohibit the dependency management plugin
Working M3 Bom Artifacts
Broken M4 Bom Artifacts
After this fix you can override any version just by modifying
gradle.propertiesThis was not possible in 7.0.0-M4 -> 7.0.3
Spring Boot Does Not Use a
.modulefile with their bom:3.5.8
4.0.0-RC2