Skip to content

Commit d1db8ab

Browse files
authored
Merge pull request #15375 from apache/feat/move-indy-config-to-gradle-plugin
feat(grails-gradle): move indy configuration from generated apps to Gradle plugin
2 parents 71f076e + 4f08683 commit d1db8ab

File tree

5 files changed

+41
-10
lines changed

5 files changed

+41
-10
lines changed

grails-doc/src/en/guide/upgrading/upgrading60x.adoc

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,16 +61,27 @@ In your gradle file, you can force a dependency upgrade via this code:
6161
}
6262
----
6363

64-
* 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:
64+
* 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 Plugins 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:
6565

6666
[source,groovy]
67-
.build.gradle
67+
.build.gradle - remove this block (no longer needed)
6868
----
69+
// This is now handled by the Grails Gradle Plugin - remove it
6970
tasks.withType(GroovyCompile).configureEach {
7071
groovyOptions.optimizationOptions.indy = false
7172
}
7273
----
7374

75+
To re-enable invokedynamic, use the `grails` extension in your `build.gradle`:
76+
77+
[source,groovy]
78+
.build.gradle
79+
----
80+
grails {
81+
indy = true
82+
}
83+
----
84+
7485
==== 3. Unified Project Version
7586

7687
Grails 7 moved to a mono repository.

grails-forge/grails-forge-core/src/main/java/org/grails/forge/feature/build/gradle/templates/buildGradle.rocker.raw

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,3 @@ assets {
142142

143143
}
144144

145-
// https://github.com/apache/grails-core/issues/15321
146-
tasks.withType(GroovyCompile).configureEach {
147-
groovyOptions.optimizationOptions.indy = false
148-
}

grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/core/GrailsExtension.groovy

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import groovy.transform.CompileStatic
2323
import org.apache.tools.ant.taskdefs.condition.Os
2424
import org.gradle.api.Project
2525
import org.gradle.api.artifacts.dsl.DependencyHandler
26+
import org.gradle.api.provider.Property
2627
import org.gradle.util.internal.ConfigureUtil
2728

2829
import grails.util.Environment
@@ -42,6 +43,7 @@ class GrailsExtension {
4243
GrailsExtension(Project project) {
4344
this.project = project
4445
this.pluginDefiner = new PluginDefiner(project)
46+
this.indy = project.objects.property(Boolean).convention(false)
4547
}
4648

4749
/**
@@ -92,6 +94,18 @@ class GrailsExtension {
9294
*/
9395
boolean micronautAutoSetup = true
9496

97+
/**
98+
* Whether to enable Groovy's invokedynamic (indy) bytecode instruction for dynamic Groovy method dispatch.
99+
* Disabled by default to improve performance (see GitHub issue #15293).
100+
* When enabled, Groovy uses JVM invokedynamic instead of traditional callsite caching.
101+
* To enable invokedynamic in build.gradle: grails { indy = true }
102+
*/
103+
final Property<Boolean> indy
104+
105+
void setIndy(boolean enabled) {
106+
this.indy.set(enabled)
107+
}
108+
95109
DependencyHandler getPlugins() {
96110
if (pluginDefiner == null) {
97111
pluginDefiner = new PluginDefiner(project)

grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/core/GrailsGradlePlugin.groovy

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,8 @@ class GrailsGradlePlugin extends GroovyPlugin {
186186
private void configureGroovyCompiler(Project project) {
187187
Provider<RegularFile> groovyCompilerConfigFile = project.layout.buildDirectory.file('grailsGroovyCompilerConfig.groovy')
188188

189+
GrailsExtension grailsExtension = project.extensions.findByType(GrailsExtension)
190+
189191
project.tasks.withType(GroovyCompile).configureEach { GroovyCompile c ->
190192
c.outputs.file(groovyCompilerConfigFile)
191193

@@ -218,6 +220,18 @@ class GrailsGradlePlugin extends GroovyPlugin {
218220
c.groovyOptions.configurationScript = combinedFile
219221
}
220222
}
223+
224+
// Configure indy and log status after evaluation so user's grails { } block has been applied
225+
project.afterEvaluate {
226+
boolean indyEnabled = grailsExtension?.indy?.getOrElse(false) ?: false
227+
project.tasks.withType(GroovyCompile).configureEach { GroovyCompile c ->
228+
c.groovyOptions.optimizationOptions.indy = indyEnabled
229+
}
230+
if (!indyEnabled) {
231+
project.logger.lifecycle('Grails: Groovy invokedynamic (indy) is disabled to improve performance (see issue #15293).')
232+
project.logger.lifecycle(' To enable invokedynamic: grails { indy = true } in build.gradle')
233+
}
234+
}
221235
}
222236

223237
protected Closure<String> getGroovyCompilerScript(GroovyCompile compile, Project project) {

grails-profiles/base/skeleton/build.gradle

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,3 @@ tasks.withType(Test).configureEach {
2727
useJUnitPlatform()
2828
}
2929

30-
// https://github.com/apache/grails-core/issues/15321
31-
tasks.withType(GroovyCompile).configureEach {
32-
groovyOptions.optimizationOptions.indy = false
33-
}

0 commit comments

Comments
 (0)