codeconsole opened a new pull request, #16114: URL: https://github.com/apache/grails-core/pull/16114
## Problem `GrailsGradlePlugin.configureGroovyCompiler` assigns `groovyOptions.configurationScript` from a `doFirst` on each `GroovyCompile` task. Gradle finalizes task properties before any task action runs, so from **Gradle 9.7** — where `GroovyCompileOptions` [became a lazy property](https://docs.gradle.org/9.7.0/release-notes.html) — every Groovy compilation in every Grails project fails: ``` * What went wrong: Execution failed for task ':compileGroovy' (registered by plugin class 'org.gradle.api.plugins.GroovyBasePlugin'). > The value for task ':compileGroovy' property 'groovyOptions.configurationScriptFile' is final and cannot be changed any further. ``` ``` at org.gradle.api.tasks.compile.GroovyCompileOptions.setConfigurationScript(GroovyCompileOptions.java:216) at org.grails.gradle.plugin.core.GrailsGradlePlugin$_configureGroovyCompiler_closure4$_closure37.doCall(GrailsGradlePlugin.groovy:233) ``` This blocks Grails 8 on Gradle 9.7 entirely — there is no user-side workaround, and no Gradle opt-out flag. ## Fix The combined compiler configuration script is now produced by a dedicated task that the compile task depends on. Assigning the property during configuration is necessary but not sufficient: Gradle then treats the script as an input file that must exist *before* the compile task runs, which fails on a clean build because `doFirst` runs after input validation. A producing task is what makes the file exist at the right moment. The generator task is marked `doNotTrackState`, which preserves the property the original `doFirst` was protecting — the existing comment noted that generating the script needs the resolved compile classpath, and declaring that as an input would pull the `runtimeClasspath` into the task's up-to-date check. The script is cheap to build, so it is regenerated on every build instead. Wiring moves into `afterEvaluate` so a `configurationScript` set by the build script is already in place and gets folded into the combined script rather than clobbered — preserving the merge the old execution-time read performed. Task names are read via `TaskCollection.names`, which does not realize the tasks. ## Testing - `:grails-gradle-plugins:test` passes. - Verified against a multi-project Grails 8 application (~20 subprojects, Groovy + GSP + plugins) on **both Gradle 9.6.1 and 9.7.0**: - full `bootJar` succeeds on both; - `clean` plus compilation in a single invocation succeeds (the case a `doFirst` cannot satisfy); - the generated `grailsGroovyCompilerConfig-<task>.groovy` still carries the expected `withConfig(configuration) { inline(phase: 'CONVERSION') ... }` metadata (`projectVersion`, `projectName`, `isPlugin`). Without this change, that same application fails on Gradle 9.7.0 at the first `compileGroovy`. -- 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]
