grails-core icon indicating copy to clipboard operation
grails-core copied to clipboard

Standardize on Gradle Platforms or Spring Dependency Management Gradle Plugin for grails-bom application

Open jamesfredley opened this issue 11 months ago • 7 comments

Gradle Platforms: https://docs.gradle.org/current/userguide/platforms.html implementation platform("org.grails:grails-bom:$grailsVersion")

vs io.spring.dependency-management plugin: https://docs.spring.io/spring-boot/gradle-plugin/managing-dependencies.html

dependencyManagement {
	imports {
		mavenBom "org.grails:grails-bom:$grailsVersion")
	}
}

Currently the grails-gradle-plugin automatically applies grails-bom via the Spring Dependency Management Gradle Plugin and also applies for spring-boot-dependencies, which is ALSO included in grails-bom with an import scope.

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>${spring-boot.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>  
    </dependencies>
  </dependencyManagement>

We then apply grails-bom via Gradle Platforms in build.gradle dependencies {}, buildSrc/build.gradle dependencies{} and are in the process of adding it to build.gradle buildscript{} dependencies {} to make sure versions are applied and consistent. Since build.gradle buildscript{} dependencies {} does not appear to support adding grails-bom via a Gradle Plugin to control versions, if we go the Gradle Platforms route, we should just put the lines in the build.gradle file, instead of magically applying via the grails-Gradle plugin, so that it is consistent in all locations.

We need to standardize on one or the other.

When Customizing/Overridding Managed Versions, which should be rare, overriding versions directly in the dependencies{} block, IE. runtimeOnly "org.fusesource.jansi:jansi:1.18", is quicker/simpler/easier than the two examples provided by Spring. And it is doing it in the normal dependencies location instead of having to use another mechanism.

Andy Wilkinson, the io.spring.dependency-management plugin author: https://stackoverflow.com/a/76540836/26842213

The most notable difference in terms of performance is that Gradle's platform and enforcedPlatform support should be noticeably more efficient. Speaking as the main author of the dependency management plugin, unless you want to make use of the ability to override version properties, I would encourage you to use Gradle's platform and enforcedPlatform support.

Björn Kautler: https://discuss.gradle.org/t/migrate-maven-bom-to-gradle/46023/2

The spring dependency management plugin is an obsolete relict from times when Gradle did not have built-in BOM support. Even the maintainer of that plugin recommends not to use it anymore, but to use the built-in BOM support with platform(...). So you shouldn’t use that plugin.

To consume a BOM, just use something like implementation(platform("coordinates of the bom")), or actually a version catalog instead of the coordinates directly.

jamesfredley avatar Jan 10 '25 15:01 jamesfredley

https://github.com/grails/grails-gradle-plugin/issues/382

jamesfredley avatar Jan 13 '25 16:01 jamesfredley

FYI: If we implement https://github.com/grails/grails-gradle-plugin/issues/389 and split the grails plugin gradle plugin up, this could assist in not having the dependency management applied for core libraries.

jdaugherty avatar Jan 14 '25 23:01 jdaugherty

Great write-up @jamesfredley! From my perspective, it seems that explicitly and exclusively using the Gradle Platform feature is the way forward. We’ve also discussed that some Grails libraries are or should be usable outside of Grails applications, including in Maven projects. Is this a factor in this discussion?

matrei avatar Jan 15 '25 06:01 matrei

@matrei It might help with users outside of Grails and Spring, but it think that may be limited to examples of usage where we show Gradle Platforms instead of io.spring.dependency-management to resolve versions.

Micronaut appears to be almost entirely using Gradle Platforms: https://github.com/search?q=org%3Amicronaut-projects+platform%28&type=code, but has just a few places still using io.spring.dependency-management: https://github.com/search?q=org%3Amicronaut-projects%20io.spring.dependency-management&type=code

So for Micronaut usage of Grails libraries, I think having those examples use Gradle Platforms is beneficial.

For Maven, I am not aware of any benefits yet. Maybe speed to generate the POM during build.

jamesfredley avatar Jan 15 '25 15:01 jamesfredley

Likely to be addresses as part of https://github.com/grails/grails-gradle-plugin/issues/389

jamesfredley avatar Jan 16 '25 16:01 jamesfredley

Added grails-bom on grails-forge in build.gradle buildscript{} dependencies {} to pull in versions from grails-bom:

https://github.com/grails/grails-forge/pull/510/files#diff-f5ca6d7de5a15a09487fe6a871e0746b890e78db62c44886ef68b0d9c688028d

jamesfredley avatar Feb 13 '25 03:02 jamesfredley

On hold, revisit with Gradle 9 when Gradle supports concise syntax to customize managed versions like: https://docs.spring.io/spring-boot/gradle-plugin/managing-dependencies.html#managing-dependencies.dependency-management-plugin.customizing.

https://github.com/gradle/gradle/issues/9160#issuecomment-2546253615

jamesfredley avatar Feb 13 '25 17:02 jamesfredley

To be able to remove the dependency management plugin, we need a solution to: https://github.com/gradle/gradle/issues/9160

jdaugherty avatar Dec 17 '25 17:12 jdaugherty