jamesfredley commented on code in PR #15365:
URL: https://github.com/apache/grails-core/pull/15365#discussion_r3142224362


##########
grails-forge/grails-forge-analytics-postgres/build.gradle:
##########
@@ -18,7 +18,6 @@
  */
 
 plugins {
-    id 'com.gradleup.shadow'
     id 'org.apache.grails.buildsrc.properties'

Review Comment:
   Verified safe to keep removed.
   
   The `io.micronaut.application` 4.6.2 plugin owns the assembly lifecycle for 
this module (`assemble`, `dockerfile`, `dockerfileNative`, `dockerBuild`, 
`dockerBuildNative`). CI deploys `grails-forge-analytics-postgres` via 
`dockerBuildNative` (native image), not `shadowJar` - confirmed by grepping the 
deploy workflows: `forge-deploy-{next,prev,prev-snapshot,release,snapshot}.yml` 
all run `./gradlew grails-forge-analytics-postgres:test` and 
`grails-forge-analytics-postgres:dockerBuildNative`, none of them invoke 
`shadowJar`.
   
   The shadow plugin is still explicitly applied where it actually produces a 
fat jar (`grails-cli`, `grails-cli-shadow`).
   
   Verified locally: `gradle :grails-forge-analytics-postgres:assemble 
:grails-forge-analytics-postgres:dockerfile 
:grails-forge-analytics-postgres:dockerfileNative` all succeed without the 
shadow plugin.



##########
grails-forge/grails-forge-api/build.gradle:
##########
@@ -47,8 +48,8 @@ dependencies {
     api 'io.micronaut:micronaut-http-client'
     api 'io.micronaut:micronaut-inject'
     api 'io.micronaut:micronaut-runtime'
-    api 'io.micronaut:micronaut-validation'
-    api group: 'javax.inject', name: 'javax.inject', version: '1'
+    api 'io.micronaut.validation:micronaut-validation'
+    api "jakarta.inject:jakarta.inject-api:$jakartaInjectVersion"

Review Comment:
   Done in dae431d4a1. Dropped the explicit `:$jakartaInjectVersion` from 
`grails-forge-api` (this file) and `grails-forge-cli`, and removed 
`jakartaInjectVersion=2.0.1` from `grails-forge/gradle.properties`.
   
   The micronaut-platform 4.10.10 BOM (already imported in both modules via 
`platform("io.micronaut.platform:micronaut-platform:$micronautVersion")`) 
manages `jakarta.inject:jakarta.inject-api` transitively through 
`io.micronaut:micronaut-core:4.10.18`. Verified with `gradle 
:grails-forge-api:dependencies --configuration compileClasspath` -> resolves to 
2.0.1, the same value we were previously hard-coding. So no version mismatch 
with the BOM, and future Micronaut bumps keep jakarta-inject in sync 
automatically.



##########
grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/core/GrailsGradlePlugin.groovy:
##########
@@ -968,12 +975,17 @@ ${importStatements}
     @CompileDynamic
     protected TaskProvider<Task> createNative2AsciiTask(TaskContainer tasks, 
src, dest) {
         TaskProvider<Task> native2asciiTask = 
tasks.register('native2ascii').configure {
+            it.inputs.dir(src)
+            it.outputs.dir(dest)
+
+            // Capture ant builder at configuration time to avoid Task.project 
access at execution time

Review Comment:
   Done in 5d21fc3a39 (also dropped the second `// See: ...` doc-link line).



##########
grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/profiles/GrailsProfileGradlePlugin.groovy:
##########
@@ -87,9 +87,14 @@ class GrailsProfileGradlePlugin implements Plugin<Project> {
         project.configurations.named('runtimeElements')
                 .configure { it.extendsFrom(runtimeOnlyConfiguration.get()) }
 
-        TaskProvider<Task> processProfileResourcesTask = 
project.tasks.register('processProfileResources')
-        processProfileResourcesTask.configure { Task task ->
+        // Use Sync task type instead of project.sync in doLast to avoid 
Task.project access at execution time

Review Comment:
   Done in 5d21fc3a39 (also dropped the second `// See: ...` doc-link line).



##########
grails-test-examples/plugins/issue-11767/build.gradle:
##########
@@ -45,3 +41,61 @@ apply {
     from 
rootProject.layout.projectDirectory.file('gradle/functional-test-config.gradle')
     from 
rootProject.layout.projectDirectory.file('gradle/grails-extension-gradle-config.gradle')
 }
+
+// Root-cause fix for duplicate META-INF/spring-configuration-metadata.json:
+//
+// This plugin intentionally exposes both a Java bean 
(PluginJavaMicronautBean) and a
+// Groovy bean (PluginGroovyMicronautBean) that share the 
@ConfigurationProperties('my')
+// prefix to exercise the original issue 11767 scenario. As a side effect, two 
different
+// Micronaut tools produce the same metadata file:
+//   - micronaut-inject-java runs as a Java annotation processor during 
compileJava and
+//     writes 
build/classes/java/main/META-INF/spring-configuration-metadata.json
+//     describing PluginJavaMicronautBean.
+//   - micronaut-inject-groovy (pulled in transitively via grails-micronaut) 
runs as a
+//     Groovy AST transform during compileGroovy and writes
+//     build/classes/groovy/main/META-INF/spring-configuration-metadata.json 
describing
+//     PluginGroovyMicronautBean.
+// The two files are not equivalent: each describes the beans visible to its 
own compiler.
+// The shared CompilePlugin convention sets jar.duplicatesStrategy = FAIL so 
the build
+// surfaces any double-configuration. Here the duplicate is by design, so we 
merge the
+// two JSON documents into a single file (preserving every group / property / 
hint) and
+// remove the now-merged source so the jar task sees exactly one metadata 
file. This is
+// preferable to dropping one of the documents (DuplicatesStrategy.EXCLUDE) 
because that
+// would silently lose the bean type information for one of the languages.
+def mergeMicronautConfigMetadata = 
tasks.register('mergeMicronautConfigMetadata') {
+    description = 'Merges the spring-configuration-metadata.json emitted 
separately by ' +
+            'micronaut-inject-java and micronaut-inject-groovy into one 
combined document.'
+    group = 'build'
+
+    def metadataRelativePath = 'META-INF/spring-configuration-metadata.json'
+    def javaMetadataProvider = 
layout.buildDirectory.file("classes/java/main/${metadataRelativePath}")
+    def groovyMetadataProvider = 
layout.buildDirectory.file("classes/groovy/main/${metadataRelativePath}")
+
+    // Re-run whenever either compile step emits new metadata; the task 
mutates files
+    // inside the compile output directories so we cannot rely on standard 
up-to-date
+    // tracking. The work is cheap (two small JSON files) so always running is 
acceptable.
+    outputs.upToDateWhen { false }

Review Comment:
   Refactored properly in d9a218175a.
   
   The merge task now:
   
   - Writes to a new `build/merged-spring-configuration-metadata/` directory 
instead of mutating compile outputs.
   - Declares `inputs.files(provider { ... })` filtered to existing files at 
execution time, plus an `outputs.file(...)` and `outputs.cacheIf { true }` so 
Gradle can cache it.
   - `dependsOn compileJava, compileGroovy` so the compile output dirs always 
populate before the merge runs.
   - The `jar` task uses an `eachFile` filter to drop the per-compiler copies 
but keep the merged copy (a global `exclude` would have discarded the merged 
document too).
   
   Verified:
   
   - A second `gradle :grails-test-examples-plugins-issue-11767:jar` invocation 
reports `compileJava`, `compileGroovy`, `mergeMicronautConfigMetadata` and 
`jar` all UP-TO-DATE - the always-rerun behavior is gone.
   - The produced jar contains exactly one 
`META-INF/spring-configuration-metadata.json` with both 
`PluginJavaMicronautBean` and `PluginGroovyMicronautBean` entries merged 
(groups + properties).
   - Consumer app (`:grails-test-examples-issue-11767:compileGroovy`) still 
compiles cleanly.
   
   Also dropped the long block comment - the inline 7-line summary above the 
task is enough.



##########
grails-forge/test-core/build.gradle:
##########
@@ -59,15 +59,15 @@ dependencies {
         testCompileOnly 
"io.micronaut:micronaut-inject-groovy:$micronautVersion"
     }
 
-    testImplementation "org.codehaus.groovy:groovy:$groovyVersion"
+    testImplementation "org.apache.groovy:groovy:$groovyVersion"

Review Comment:
   Fixed properly in 014355310b.
   
   - `groovyVersion=4.0.31` removed from `grails-forge/gradle.properties`.
   - All 16 `:$groovyVersion` references across forge dropped (`test-core`, 
`grails-forge-api`, `grails-forge-cli`, `grails-forge-core`, 
`gradle/doc-config.gradle`).
   - The `eachDependency { details.useVersion(groovyVersion) }` 
resolutionStrategy override removed from `grails-forge-api`, 
`grails-forge-cli`, and `grails-forge-core`. The `spock-core` override stays - 
that one is still needed because the micronaut-platform BOM's spock version 
differs from ours.
   
   With the override gone, Gradle's conflict resolution lets the BOM-managed 
version win:
   
   `org.apache.groovy:groovy-bom` -> 4.0.28, `org.apache.groovy:groovy` -> 
4.0.28, `org.apache.groovy:groovy-test` -> 4.0.28.
   
   Forge now tracks the Groovy version Micronaut 4.10.10 was actually built 
against (4.0.28). grails-core stays on 4.0.31 - the two builds are independent 
composite projects with their own platform choices. Verified with `gradle 
:grails-forge-api:dependencies --configuration testRuntimeClasspath` and 
`gradle :grails-forge-{api,cli,core,test-core}:compileTestGroovy`.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to