feat(grails-gradle): move indy configuration from generated apps to Gradle plugin#15375
Conversation
8dbb060 to
f4a0ed7
Compare
|
#15321 was already closed by adding it to the gradle file. Can you help me understand why you want to move this to the extension? The current implementation will break anyone who tries to override it - which is something significant enough that I think it should at least go into 7.1.x. Are you wanting to change this default to true in Grails 8? That's the only reason I can think to move it to the extension. |
| * When enabled, Groovy uses JVM invokedynamic instead of traditional callsite caching. | ||
| * To enable invokedynamic in build.gradle: grails { indy = true } | ||
| */ | ||
| boolean indy = false |
There was a problem hiding this comment.
For anyone that generated an application with the 7.0.6+ codeline, it will now flip it back to false - making this a breaking change.
|
The change introduces a configurable 'indy' option in GrailsExtension, defaulting to false, and removes the hardcoded 'indy = false' from build templates. For apps generated with 7.0.6+ that had this setting, behavior remains the same. However, existing apps without the explicit setting may see indy flipped from its previous default (likely true) to false, potentially causing a breaking change in performance or behavior. |
|
As we work on Grails 8 we may be able to achieve performance closer with some ideas from #15374 plus changes in Groovy. |
…radle plugin
Move the Groovy invokedynamic (indy) configuration from generated
build.gradle files to the Grails Gradle Plugin, centralizing the
setting and providing user feedback.
Changes:
- Add 'indy' property to GrailsExtension (default: false)
- Configure GroovyCompile tasks in GrailsGradlePlugin to use the
extension's indy setting
- Display lifecycle message explaining indy is disabled for
performance and how to enable it
- Remove hardcoded indy=false from grails-forge template
- Remove hardcoded indy=false from grails-profiles base skeleton
The message appears once per project during configuration:
Grails: Groovy invokedynamic (indy) is disabled to improve
performance (see issue #15293).
To enable invokedynamic: grails { indy = true } in build.gradle
Closes #15321
f4a0ed7 to
c9544f6
Compare
jdaugherty
left a comment
There was a problem hiding this comment.
I'm good with this going into 7.1, but we need to update the upgrade guide to point out this difference. Can you add a blurb about this change?
Users upgrading can now remove the manual tasks.withType(GroovyCompile)
block from build.gradle since the Grails Gradle Plugin handles this
automatically. Documents the new grails { indy = true } extension for
re-enabling invokedynamic.
Assisted-by: Claude Code <Claude@Claude.ai>
|
Added an update to the upgrade guide ( |
There was a problem hiding this comment.
Pull request overview
Centralizes Groovy invokedynamic (“indy”) configuration by moving it out of generated application build.gradle templates and into the Grails Gradle plugin, with an extension flag intended to let users opt back in.
Changes:
- Adds
indytoGrailsExtension(defaultfalse) and wires it intoGroovyCompiletask configuration. - Logs a lifecycle message when indy is disabled and explains how to enable it.
- Removes the hardcoded
indy = falseblocks from forge/profile templates and updates the upgrade guide accordingly.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
grails-profiles/base/skeleton/build.gradle |
Removes template-level GroovyCompile indy disabling block. |
grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/core/GrailsGradlePlugin.groovy |
Configures GroovyCompile indy based on the Grails extension; adds a lifecycle message. |
grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/core/GrailsExtension.groovy |
Introduces indy as a Property<Boolean> with default false. |
grails-forge/grails-forge-core/src/main/java/org/grails/forge/feature/build/gradle/templates/buildGradle.rocker.raw |
Removes template-level GroovyCompile indy disabling block. |
grails-doc/src/en/guide/upgrading/upgrading60x.adoc |
Updates guidance to reflect plugin-managed indy and documents re-enabling it. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/core/GrailsGradlePlugin.groovy
Outdated
Show resolved
Hide resolved
grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/core/GrailsExtension.groovy
Show resolved
Hide resolved
Add setIndy(boolean) to GrailsExtension so grails { indy = true } DSL
syntax works with the Property<Boolean> field. Move the GroovyCompile
indy configuration into afterEvaluate to ensure it reads the final
extension value after the user's build script has been evaluated.
Assisted-by: Claude Code <Claude@Claude.ai>
| ---- | ||
|
|
||
| * By default, Groovy 4 switches away from callsite optimizations and uses invokedynamic instead. This can result in performance regressions compared to Grails 6. Groovy 5 will remove the ability to disable invokedynamic, but to disable it for Groovy 4, modify your `build.gradle` to include the following: | ||
| * By default, Groovy 4 switches away from callsite optimizations and uses invokedynamic instead. This can result in performance regressions compared to Grails 6. The Grails Gradle Plugin now automatically disables invokedynamic for all `GroovyCompile` tasks (see https://github.com/apache/grails-core/issues/15293[#15293]). If you have a manual `tasks.withType(GroovyCompile)` block in your `build.gradle` that sets `indy = false`, you can safely remove it: |
There was a problem hiding this comment.
I would say "plugins" since applying any of them will cause it to disable.
There was a problem hiding this comment.
Very good point.
jdaugherty
left a comment
There was a problem hiding this comment.
Minor comment, otherwise good to merge.
|
@jamesfredley reviewing #15396 made me realize that we're not really testing both ways - with indy & without. This change will effectively make it so our apps only test with it off. Is this a good idea given that indy is more problematic? |
Add indy: [false, true] matrix dimension to all functional test CI jobs (functional, hibernate5, mongodb, forge) to ensure Groovy invokedynamic is tested both enabled and disabled. After PR apache#15375 moved indy configuration from generated build.gradle files to the Grails Gradle Plugin, CI was only testing with the default (indy=false). This leaves indy=true completely untested. Changes: - Add grailsIndy property toggle to grails-extension-gradle-config.gradle so test example projects respect -PgrailsIndy=true/false - Add indy matrix to functional, hibernate5Functional, mongodbFunctional, and buildForge CI jobs - Include indy status in job names for clear CI dashboard visibility Assisted-by: Claude Code <Claude@Claude.ai>
|
@jdaugherty That's a big one: PR: #15415 |
Summary
Move the Groovy invokedynamic (indy) configuration from generated
build.gradlefiles to the Grails Gradle Plugin, centralizing the setting and providing user feedback.Changes
indyproperty toGrailsExtension(default:false)GroovyCompiletasks inGrailsGradlePluginto use the extension's indy settingindy=falsefrom grails-forge templateindy=falsefrom grails-profiles base skeletonUser Experience
The message appears once per project during configuration:
Users can enable indy in their
build.gradle:grails { indy = true }Testing
Closes #15321
Documentation
upgrading60x.adoc) to reflect that the Grails Gradle Plugin now handles indy configuration automaticallytasks.withType(GroovyCompile)block from theirbuild.gradlegrails { indy = true }extension for re-enabling invokedynamic