You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@grails.apache.org by jd...@apache.org on 2026/04/09 05:43:26 UTC
(grails-core) 04/04: Ensure dependencies match the grails-bom on micronaut
This is an automated email from the ASF dual-hosted git repository.
jdaugherty pushed a commit to branch spring-boot-4
in repository https://gitbox.apache.org/repos/asf/grails-core.git
commit 2b9e07544387200a2e0f17c8519acb19c6d2924f
Author: James Daugherty <jd...@jdresources.net>
AuthorDate: Thu Apr 9 01:43:14 2026 -0400
Ensure dependencies match the grails-bom on micronaut
---
dependencies.gradle | 13 +++++
.../src/en/guide/upgrading/upgrading80x.adoc | 33 ++++++++++++-
.../forge/build/dependencies/Coordinate.java | 4 ++
.../forge/build/dependencies/Dependency.java | 29 ++++++++---
.../build/dependencies/DependencyCoordinate.java | 8 ++++
.../forge/build/gradle/GradleDependency.java | 4 +-
.../grails/forge/feature/grails/GrailsBase.java | 7 ++-
.../gradle/plugin/core/GrailsGradlePlugin.groovy | 56 ++++++++++++++++++----
grails-micronaut/build.gradle | 5 +-
grails-test-examples/issue-11767/build.gradle | 2 +-
.../micronaut-groovy-only/build.gradle | 2 +-
grails-test-examples/micronaut/build.gradle | 4 +-
.../mongodb/springboot/build.gradle | 2 +-
.../plugins/issue-11767/build.gradle | 2 +-
.../plugins/micronaut-singleton/build.gradle | 2 +-
15 files changed, 146 insertions(+), 27 deletions(-)
diff --git a/dependencies.gradle b/dependencies.gradle
index b0e1a95bfb..4665bf6bcf 100644
--- a/dependencies.gradle
+++ b/dependencies.gradle
@@ -83,6 +83,8 @@ ext {
'rxjava2.version' : '2.2.21',
'rxjava3.version' : '3.1.12',
'selenium.version' : '4.38.0',
+ 'kotlin.version' : '2.2.21',
+ 'mockito.version' : '5.20.0',
'spock.version' : '2.3-groovy-4.0',
'sitemesh.version' : '2.6.0',
'starter-sitemesh.version' : '3.2.2',
@@ -103,6 +105,7 @@ ext {
'bootstrap-icons' : "org.webjars.npm:bootstrap-icons:${bomDependencyVersions['bootstrap-icons.version']}",
'commons-codec' : "commons-codec:commons-codec:${bomDependencyVersions['commons-codec.version']}",
'commons-lang3' : "org.apache.commons:commons-lang3:${bomDependencyVersions['commons-lang3.version']}",
+ 'byte-buddy-agent' : "net.bytebuddy:byte-buddy-agent:${gradleBomDependencyVersions['byte-buddy.version']}",
'geb-spock' : "org.apache.groovy.geb:geb-spock:${bomDependencyVersions['geb-spock.version']}",
// start - restate the groovy-bom includes here because the spring dependency management will pick the library from spring-boot-dependencies otherwise
'groovy' : "org.apache.groovy:groovy:${bomDependencyVersions['groovy.version']}",
@@ -136,6 +139,16 @@ ext {
'groovy-xml' : "org.apache.groovy:groovy-xml:${bomDependencyVersions['groovy.version']}",
'groovy-yaml' : "org.apache.groovy:groovy-yaml:${bomDependencyVersions['groovy.version']}",
// end - restate the groovy-bom here because the spring dependency management
+ // start - restate versions managed by Spring Boot / Spock BOMs so enforcedPlatform can enforce them
+ // when micronaut is used (Micronaut 5 platform declares higher versions that override preferences)
+ 'kotlin-stdlib' : "org.jetbrains.kotlin:kotlin-stdlib:${bomDependencyVersions['kotlin.version']}",
+ 'kotlin-stdlib-common' : "org.jetbrains.kotlin:kotlin-stdlib-common:${bomDependencyVersions['kotlin.version']}",
+ 'kotlin-stdlib-jdk7' : "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${bomDependencyVersions['kotlin.version']}",
+ 'kotlin-stdlib-jdk8' : "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${bomDependencyVersions['kotlin.version']}",
+ 'mockito-core' : "org.mockito:mockito-core:${bomDependencyVersions['mockito.version']}",
+ 'spock-core' : "org.spockframework:spock-core:${bomDependencyVersions['spock.version']}",
+ 'spock-spring' : "org.spockframework:spock-spring:${bomDependencyVersions['spock.version']}",
+ // end - restate versions managed by inherited BOMs
'jquery' : "org.webjars.npm:jquery:${bomDependencyVersions['jquery.version']}",
'liquibase-hibernate5' : "org.liquibase:liquibase:${bomDependencyVersions['liquibase-hibernate5.version']}",
'liquibase-hibernate5-cdi' : "org.liquibase:liquibase-cdi:${bomDependencyVersions['liquibase-hibernate5.version']}",
diff --git a/grails-doc/src/en/guide/upgrading/upgrading80x.adoc b/grails-doc/src/en/guide/upgrading/upgrading80x.adoc
index 8b0259a3c5..5247ad406a 100644
--- a/grails-doc/src/en/guide/upgrading/upgrading80x.adoc
+++ b/grails-doc/src/en/guide/upgrading/upgrading80x.adoc
@@ -143,7 +143,9 @@ import org.springframework.http.HttpStatus
response.status = HttpStatus.FOUND.value()
----
-==== 7. Micronaut Integration - CLASSIC Boot Loader Removed
+==== 7. Micronaut Integration Changes
+
+===== 7.1 CLASSIC Boot Loader Removed
Spring Boot 4 removed the `CLASSIC` loader implementation (`LoaderImplementation.CLASSIC`).
In Grails 7, the Grails Gradle Plugin automatically configured `bootJar` and `bootWar` tasks to use the `CLASSIC` loader when the `grails-micronaut` plugin was detected.
@@ -167,6 +169,35 @@ tasks.withType(BootArchive).configureEach {
* The `grails-micronaut` plugin continues to work with Spring Boot 4's default loader.
If you experience issues running your Micronaut-enabled Grails application via `java -jar`, please report them to the https://github.com/apache/grails-core/issues[Grails issue tracker].
+===== 7.2 enforcedPlatform Required for grails-bom
+
+When using Micronaut, the `grails-bom` **must** be applied as `enforcedPlatform` instead of `platform`.
+The Micronaut 5 platform declares its own managed dependency versions that conflict with those managed by the `grails-bom`.
+Without `enforcedPlatform`, Gradle's default conflict resolution (highest version wins) allows the Micronaut platform to silently override `grails-bom` versions, leading to binary incompatibilities at runtime.
+
+For example, without `enforcedPlatform`:
+
+* **Groovy** is upgraded from 4.0.x to 5.0.x -- Groovy 5 has breaking API changes (e.g. `ArrayGroovyMethods` moved) that cause `NoClassDefFoundError` at runtime
+* **Spock** is upgraded from 2.3-groovy-4.0 to 2.4-groovy-5.0 -- compiled against Groovy 5, incompatible with Groovy 4 classes
+* **Kotlin**, **Mockito**, **Byte Buddy** are upgraded to versions not tested with the Grails stack
+
+Using `enforcedPlatform` makes all `grails-bom` constraints strictly versioned so they cannot be overridden by any transitive dependency.
+
+The Grails Gradle Plugin will error at configuration time if `grails-micronaut` is detected and `grails-bom` is not applied as `enforcedPlatform`.
+
+[source,groovy]
+.build.gradle
+----
+dependencies {
+ // enforcedPlatform is required when using grails-micronaut
+ implementation enforcedPlatform("org.apache.grails:grails-bom:$grailsVersion")
+
+ implementation 'org.apache.grails:grails-micronaut'
+}
+----
+
+NOTE: Applications generated by the Grails Forge automatically use `enforcedPlatform` when the Micronaut feature is selected.
+
==== 8. Enum Serialization Default Changed
As announced in the Grails 7.0.2 deprecation notice, the `SimpleEnumMarshaller` is now the default for JSON and XML enum serialization in Grails 8.
diff --git a/grails-forge/grails-forge-core/src/main/java/org/grails/forge/build/dependencies/Coordinate.java b/grails-forge/grails-forge-core/src/main/java/org/grails/forge/build/dependencies/Coordinate.java
index c96a4c3702..5fb61cdf75 100644
--- a/grails-forge/grails-forge-core/src/main/java/org/grails/forge/build/dependencies/Coordinate.java
+++ b/grails-forge/grails-forge-core/src/main/java/org/grails/forge/build/dependencies/Coordinate.java
@@ -50,4 +50,8 @@ public interface Coordinate {
String getVersion();
boolean isPom();
+
+ default boolean isEnforced() {
+ return false;
+ }
}
diff --git a/grails-forge/grails-forge-core/src/main/java/org/grails/forge/build/dependencies/Dependency.java b/grails-forge/grails-forge-core/src/main/java/org/grails/forge/build/dependencies/Dependency.java
index c61dd6777c..bc43b5fc7b 100644
--- a/grails-forge/grails-forge-core/src/main/java/org/grails/forge/build/dependencies/Dependency.java
+++ b/grails-forge/grails-forge-core/src/main/java/org/grails/forge/build/dependencies/Dependency.java
@@ -36,6 +36,7 @@ public final class Dependency {
private final int order;
private final boolean annotationProcessorPriority;
private final boolean pom;
+ private final boolean enforced;
private Dependency(Scope scope,
String groupId,
@@ -46,7 +47,8 @@ public final class Dependency {
boolean requiresLookup,
boolean annotationProcessorPriority,
int order,
- boolean pom) {
+ boolean pom,
+ boolean enforced) {
this.scope = scope;
this.groupId = groupId;
this.artifactId = artifactId;
@@ -57,6 +59,7 @@ public final class Dependency {
this.annotationProcessorPriority = annotationProcessorPriority;
this.order = order;
this.pom = pom;
+ this.enforced = enforced;
}
private Dependency(Scope scope,
@@ -67,8 +70,9 @@ public final class Dependency {
boolean requiresLookup,
boolean annotationProcessorPriority,
int order,
- boolean pom) {
- this(scope, groupId, artifactId, version, versionProperty, null, requiresLookup, annotationProcessorPriority, order, pom);
+ boolean pom,
+ boolean enforced) {
+ this(scope, groupId, artifactId, version, versionProperty, null, requiresLookup, annotationProcessorPriority, order, pom, enforced);
}
public Scope getScope() {
@@ -101,6 +105,10 @@ public final class Dependency {
return pom;
}
+ public boolean isEnforced() {
+ return enforced;
+ }
+
public static Builder builder() {
return new Builder();
}
@@ -119,7 +127,8 @@ public final class Dependency {
false,
annotationProcessorPriority,
order,
- coordinate.isPom());
+ coordinate.isPom(),
+ coordinate.isEnforced());
}
public Dependency scope(Scope newScope) {
@@ -132,7 +141,8 @@ public final class Dependency {
requiresLookup,
annotationProcessorPriority,
order,
- pom);
+ pom,
+ enforced);
}
public boolean isAnnotationProcessorPriority() {
@@ -172,6 +182,7 @@ public final class Dependency {
private boolean template = false;
private boolean annotationProcessorPriority = false;
private boolean pom = false;
+ private boolean enforced = false;
public Builder scope(@NonNull Scope scope) {
if (template) {
@@ -325,6 +336,11 @@ public final class Dependency {
return this;
}
+ public Builder enforced(boolean enforced) {
+ this.enforced = enforced;
+ return this;
+ }
+
public Dependency build() {
Objects.requireNonNull(scope, "The dependency scope must be set");
Objects.requireNonNull(artifactId, "The artifact id must be set");
@@ -352,7 +368,8 @@ public final class Dependency {
requiresLookup,
annotationProcessorPriority,
order,
- pom);
+ pom,
+ enforced);
}
private Builder copy() {
diff --git a/grails-forge/grails-forge-core/src/main/java/org/grails/forge/build/dependencies/DependencyCoordinate.java b/grails-forge/grails-forge-core/src/main/java/org/grails/forge/build/dependencies/DependencyCoordinate.java
index 913dd66f19..6df627bc3c 100644
--- a/grails-forge/grails-forge-core/src/main/java/org/grails/forge/build/dependencies/DependencyCoordinate.java
+++ b/grails-forge/grails-forge-core/src/main/java/org/grails/forge/build/dependencies/DependencyCoordinate.java
@@ -34,6 +34,7 @@ public class DependencyCoordinate implements Coordinate, Ordered {
private final String version;
private final int order;
private final boolean pom;
+ private final boolean enforced;
public DependencyCoordinate(Dependency dependency) {
this(dependency, false);
@@ -49,6 +50,7 @@ public class DependencyCoordinate implements Coordinate, Ordered {
}
order = dependency.getOrder();
pom = dependency.isPom();
+ enforced = dependency.isEnforced();
}
public DependencyCoordinate(String groupId,
@@ -61,6 +63,7 @@ public class DependencyCoordinate implements Coordinate, Ordered {
this.version = version;
this.order = order;
this.pom = pom;
+ this.enforced = false;
}
@Override
@@ -91,6 +94,11 @@ public class DependencyCoordinate implements Coordinate, Ordered {
return pom;
}
+ @Override
+ public boolean isEnforced() {
+ return enforced;
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) {
diff --git a/grails-forge/grails-forge-core/src/main/java/org/grails/forge/build/gradle/GradleDependency.java b/grails-forge/grails-forge-core/src/main/java/org/grails/forge/build/gradle/GradleDependency.java
index 7440148f40..0f72ed14a4 100644
--- a/grails-forge/grails-forge-core/src/main/java/org/grails/forge/build/gradle/GradleDependency.java
+++ b/grails-forge/grails-forge-core/src/main/java/org/grails/forge/build/gradle/GradleDependency.java
@@ -104,7 +104,9 @@ public class GradleDependency extends DependencyCoordinate {
public String toSnippet() {
String optionalSpace = gradleConfiguration == INTEGRATION_TEST_IMPLEMENTATION_TEST_FIXTURES ? "" : " ";
String snippet = gradleConfiguration.getConfigurationName() + optionalSpace;
- if (isPom()) {
+ if (isPom() && isEnforced()) {
+ snippet += "enforcedPlatform(";
+ } else if (isPom()) {
snippet += "platform(";
} else if (gradleConfiguration == INTEGRATION_TEST_IMPLEMENTATION_TEST_FIXTURES) {
snippet += "(";
diff --git a/grails-forge/grails-forge-core/src/main/java/org/grails/forge/feature/grails/GrailsBase.java b/grails-forge/grails-forge-core/src/main/java/org/grails/forge/feature/grails/GrailsBase.java
index da9a07bc45..edd85eee68 100644
--- a/grails-forge/grails-forge-core/src/main/java/org/grails/forge/feature/grails/GrailsBase.java
+++ b/grails-forge/grails-forge-core/src/main/java/org/grails/forge/feature/grails/GrailsBase.java
@@ -24,6 +24,7 @@ import org.grails.forge.application.generator.GeneratorContext;
import org.grails.forge.build.dependencies.Dependency;
import org.grails.forge.feature.DefaultFeature;
import org.grails.forge.feature.Feature;
+import org.grails.forge.feature.micronaut.GrailsMicronaut;
import org.grails.forge.options.Options;
import org.grails.forge.template.URLTemplate;
@@ -55,11 +56,15 @@ public class GrailsBase implements DefaultFeature {
@Override
public void apply(GeneratorContext generatorContext) {
- // This ensures that grails-bom forces milestones to override snapshots
+ // When micronaut is used, enforcedPlatform is required to prevent the Micronaut
+ // platform from overriding grails-bom managed versions (e.g. Groovy 5 over Groovy 4)
+ boolean useEnforced = generatorContext.isFeaturePresent(GrailsMicronaut.class);
+
generatorContext.addDependency(Dependency.builder()
.groupId("org.apache.grails")
.artifactId("grails-bom")
.pom(true)
+ .enforced(useEnforced)
.version("$grailsVersion")
.implementation());
diff --git a/grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/core/GrailsGradlePlugin.groovy b/grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/core/GrailsGradlePlugin.groovy
index 88fd83777b..3d94a550f7 100644
--- a/grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/core/GrailsGradlePlugin.groovy
+++ b/grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/core/GrailsGradlePlugin.groovy
@@ -41,6 +41,7 @@ import org.gradle.api.Task
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.Dependency
import org.gradle.api.artifacts.DependencyResolveDetails
+import org.gradle.api.artifacts.ModuleDependency
import org.gradle.api.artifacts.DependencySet
import org.gradle.api.attributes.AttributeMatchingStrategy
import org.gradle.api.file.DuplicatesStrategy
@@ -277,7 +278,7 @@ class GrailsGradlePlugin implements Plugin<Project> {
${importStatements}
}
}
- """
+ """ as String
}
}
@@ -394,10 +395,10 @@ ${importStatements}
Task buildPropertiesTask = project.tasks.create('buildProperties')
Map<String, Object> buildPropertiesContents = [
- 'grails.env': Environment.isSystemSet() ? Environment.getCurrent().getName() : Environment.PRODUCTION.getName(),
- 'info.app.name': project.name,
- 'info.app.version': project.version instanceof Serializable ? project.version : project.version.toString(),
- 'info.app.grailsVersion': project.properties.get('grailsVersion')
+ 'grails.env': Environment.isSystemSet() ? Environment.getCurrent().getName() : Environment.PRODUCTION.getName(),
+ 'info.app.name': project.name,
+ 'info.app.version': project.version instanceof Serializable ? project.version : project.version.toString(),
+ 'info.app.grailsVersion': project.properties.get('grailsVersion')
]
buildPropertiesTask.inputs.properties(buildPropertiesContents)
@@ -421,7 +422,7 @@ ${importStatements}
@CompileStatic
protected void configureMicronaut(Project project) {
project.afterEvaluate {
- boolean micronautEnabled = project.getConfigurations().getByName('implementation').getDependencies().findAll { Dependency dep -> dep.group == 'org.apache.grails' && dep.name == 'grails-micronaut' } as boolean
+ boolean micronautEnabled = project.getConfigurations().getByName('runtimeClasspath').getAllDependencies().findAll { Dependency dep -> dep.group == 'org.apache.grails' && dep.name == 'grails-micronaut' } as boolean
if (!micronautEnabled) {
return
}
@@ -438,6 +439,12 @@ ${importStatements}
throw new GradleException('`micronautPlatformVersion` property must be set to use the Grails Micronaut plugin.')
}
+ // Validate that grails-bom is applied as enforcedPlatform. Micronaut 5's platform
+ // declares Groovy 5, Kotlin 2.3, etc. which override the grails-bom via conflict
+ // resolution. enforcedPlatform makes all BOM constraints strictly versioned so they
+ // cannot be overridden by transitive dependencies.
+ validateEnforcedBom(project)
+
// grails-micronaut exports the platform, but force the version to the user specified version
project.configurations.configureEach { Configuration configuration ->
configuration.resolutionStrategy.eachDependency { DependencyResolveDetails details ->
@@ -453,6 +460,36 @@ ${importStatements}
}
}
+ /**
+ * Validates that grails-bom is applied as an enforcedPlatform when micronaut is used.
+ * Without enforcedPlatform, the Micronaut platform's version constraints (e.g. Groovy 5,
+ * Kotlin 2.3, Spock 2.4) will override the grails-bom versions via conflict resolution.
+ */
+ @CompileStatic
+ protected static void validateEnforcedBom(Project project) {
+ Configuration implConfig = project.configurations.findByName('implementation')
+ if (implConfig == null) {
+ return
+ }
+
+ for (Dependency dep : implConfig.dependencies) {
+ if (dep.name == 'grails-bom' && dep instanceof ModuleDependency) {
+ Object categoryAttr = ((ModuleDependency) dep).attributes.getAttribute(
+ org.gradle.api.attributes.Category.CATEGORY_ATTRIBUTE
+ )
+ if (categoryAttr != null && categoryAttr.toString() == org.gradle.api.attributes.Category.ENFORCED_PLATFORM) {
+ return // correctly configured
+ }
+ throw new GradleException(
+ "Project '${project.name}' uses Micronaut but applies grails-bom as a regular platform. " +
+ 'Micronaut\'s platform declares higher versions of Groovy, Spock, and Kotlin that will ' +
+ 'override the grails-bom via conflict resolution. Change to:\n\n' +
+ ' implementation enforcedPlatform(project(\':grails-bom\'))\n'
+ )
+ }
+ }
+ }
+
@CompileStatic
protected void configureGroovy(Project project) {
final String groovyVersion = project.properties['groovy.version']
@@ -890,9 +927,9 @@ ${importStatements}
}
Map<String, String> replaceTokens = [
- 'info.app.name': project.name,
- 'info.app.version': project.version?.toString(),
- 'info.app.grailsVersion': grailsVersion
+ 'info.app.name': project.name,
+ 'info.app.version': project.version?.toString(),
+ 'info.app.grailsVersion': grailsVersion
]
task.from(project.relativePath('src/main/templates')) { spec ->
@@ -1031,6 +1068,7 @@ ${importStatements}
@CompileStatic
private static final class OnlyOneGrailsPlugin {
+
String pluginClassname
}
}
diff --git a/grails-micronaut/build.gradle b/grails-micronaut/build.gradle
index a2dfd64072..a47f2a6190 100644
--- a/grails-micronaut/build.gradle
+++ b/grails-micronaut/build.gradle
@@ -39,8 +39,9 @@ dependencies {
api platform("io.micronaut.platform:micronaut-platform:$micronautPlatformVersion")
api 'io.micronaut.spring:micronaut-spring-boot-starter'
- // For the grails plugin interface
- compileOnly platform(project(':grails-bom'))
+ // For the grails plugin interface. enforcedPlatform ensures Groovy 4.x from the
+ // grails-bom wins over Groovy 5.x from the micronaut platform during compilation.
+ compileOnly enforcedPlatform(project(':grails-bom'))
compileOnly project(':grails-core')
}
diff --git a/grails-test-examples/issue-11767/build.gradle b/grails-test-examples/issue-11767/build.gradle
index 949b36c6b0..aaea342506 100644
--- a/grails-test-examples/issue-11767/build.gradle
+++ b/grails-test-examples/issue-11767/build.gradle
@@ -28,7 +28,7 @@ group = 'issue11767.app'
apply plugin: 'org.apache.grails.gradle.grails-web'
dependencies {
- implementation platform(project(':grails-bom'))
+ implementation enforcedPlatform(project(':grails-bom'))
implementation 'org.apache.grails:grails-dependencies-starter-web'
implementation 'org.apache.grails:grails-micronaut'
diff --git a/grails-test-examples/micronaut-groovy-only/build.gradle b/grails-test-examples/micronaut-groovy-only/build.gradle
index b23298c91e..942e545cf6 100644
--- a/grails-test-examples/micronaut-groovy-only/build.gradle
+++ b/grails-test-examples/micronaut-groovy-only/build.gradle
@@ -34,7 +34,7 @@ apply plugin: 'org.apache.grails.gradle.grails-web'
// processors when grails-micronaut is present on the classpath.
dependencies {
- implementation platform(project(':grails-bom'))
+ implementation enforcedPlatform(project(':grails-bom'))
implementation 'org.apache.grails:grails-dependencies-starter-web'
implementation 'org.apache.grails:grails-micronaut'
diff --git a/grails-test-examples/micronaut/build.gradle b/grails-test-examples/micronaut/build.gradle
index 0dfb5421d6..e8fb8045ff 100644
--- a/grails-test-examples/micronaut/build.gradle
+++ b/grails-test-examples/micronaut/build.gradle
@@ -37,7 +37,7 @@ apply plugin: 'cloud.wondrify.asset-pipeline'
apply plugin: 'org.apache.grails.gradle.grails-gsp'
dependencies {
- implementation platform(project(':grails-bom'))
+ implementation enforcedPlatform(project(':grails-bom'))
implementation "io.micronaut:micronaut-http-client:$micronautHttpClientVersion"
implementation "io.micronaut:micronaut-retry:$micronautHttpClientVersion"
@@ -51,7 +51,7 @@ dependencies {
annotationProcessor 'io.micronaut:micronaut-inject-java'
annotationProcessor 'jakarta.annotation:jakarta.annotation-api'
- testAndDevelopmentOnly platform(project(':grails-bom'))
+ testAndDevelopmentOnly enforcedPlatform(project(':grails-bom'))
testAndDevelopmentOnly 'org.apache.grails:grails-dependencies-assets'
runtimeOnly 'cloud.wondrify:asset-pipeline-grails'
diff --git a/grails-test-examples/mongodb/springboot/build.gradle b/grails-test-examples/mongodb/springboot/build.gradle
index 5855d0b24e..2282d12127 100644
--- a/grails-test-examples/mongodb/springboot/build.gradle
+++ b/grails-test-examples/mongodb/springboot/build.gradle
@@ -27,7 +27,7 @@ apply plugin: 'org.springframework.boot'
dependencies {
- implementation platform(project(':grails-bom'))
+ implementation enforcedPlatform(project(':grails-bom'))
implementation 'org.apache.grails:grails-data-mongodb-spring-boot'
implementation 'org.apache.groovy:groovy'
diff --git a/grails-test-examples/plugins/issue-11767/build.gradle b/grails-test-examples/plugins/issue-11767/build.gradle
index 1dff7f2e8f..ee62b49682 100644
--- a/grails-test-examples/plugins/issue-11767/build.gradle
+++ b/grails-test-examples/plugins/issue-11767/build.gradle
@@ -32,7 +32,7 @@ tasks.withType(Jar).configureEach {
}
dependencies {
- implementation platform(project(':grails-bom'))
+ implementation enforcedPlatform(project(':grails-bom'))
implementation 'org.apache.grails:grails-core'
implementation 'org.apache.grails:grails-micronaut'
diff --git a/grails-test-examples/plugins/micronaut-singleton/build.gradle b/grails-test-examples/plugins/micronaut-singleton/build.gradle
index 0fc1861438..1dc402f1cc 100644
--- a/grails-test-examples/plugins/micronaut-singleton/build.gradle
+++ b/grails-test-examples/plugins/micronaut-singleton/build.gradle
@@ -28,7 +28,7 @@ group = 'com.example.grails.plugins'
apply plugin: 'org.apache.grails.gradle.grails-plugin'
dependencies {
- implementation platform(project(':grails-bom'))
+ implementation enforcedPlatform(project(':grails-bom'))
api 'org.apache.grails:grails-dependencies-starter-web'
api 'org.apache.grails:grails-micronaut'