Property-driven dependency versions in published POM


I’m building a library and I’d like the dependency versions to be extracted to properties when the library is published to Maven repository (similarly to e.g. Maven Central: org.springframework.boot:spring-boot-parent:3.2.1)

If I use properties in ext section and then reference them later in build.gradle when declaring dependencies, the resolution works as expected (i.e. properties are used), however, when this is published to Maven repository, the versions in the generated and published POM are “hardcoded” (i.e. the properties have been resolved and replaced with actual values).

Is there a way how to publish library to Maven repo in a way where properties remain as properties so that the consuming client may easily override them (e.g. when they need to patch some dependency, etc)?

If they want to override the version from Gradle, they can simply use a version constraint.
If they want to override the version from Maven, they can simply add the dependency explicitly in their POM.
So it should not really necessary to have “property-based” versions in the published POM.

For a Gradle consumer it wouldn’t work anyway for two reasons, 1. assuming you publish Gradle Module Metadata, the POM is not used, 2. even if the POM is used, I don’t think you could use the properties for overriding the version but would use a dependency constraint anyway.

There’s a good reason why e.g. Spring Boot does it the way it does.

Yes, theoretically consumers may override dependencies explicitly, but if you have a library that has big dependency tree that contains multiple libraries from the same ecosystem bound by version (e.g. Spring, Jackson, …), having one property that controls the version is better than having the client redeclare all related libraries just because they want to increase the version.

You can take a look e.g at Dependency Versions and see how many libraries would be affected when e.g. spring-framework.version is modified.

I.e. what you provided is indeed a workaround (and not a user friendly one), however, I’d be interested in a proper solution (if it is possible when building with Gradle).

Nah, Spring Boot is different.
They provide a BOM with the respective version constraints.
If you consume that BOM using the Spring Dependency Management plugin you could indeed change those versions using the property names.
But actually that plugin is an obsolete relict from times when Gradle did not have built-in BOM support, by now does more harm than good, and even the maintainer of that plugin recommends not to use it anymore but instead the built-in BOM support.
And there again you would then use version constraints to change the versions coming from the BOM.

If you meant how to publish such a BOM with Gradle, that is documented here: The Java Platform Plugin