Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions grails-doc/src/en/guide/upgrading/upgrading60x.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,27 @@ In your gradle file, you can force a dependency upgrade via this code:
}
----

* 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:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say "plugins" since applying any of them will cause it to disable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very good point.


[source,groovy]
.build.gradle
.build.gradle - remove this block (no longer needed)
----
// This is now handled by the Grails Gradle Plugin - remove it
tasks.withType(GroovyCompile).configureEach {
groovyOptions.optimizationOptions.indy = false
}
----

To re-enable invokedynamic, use the `grails` extension in your `build.gradle`:

[source,groovy]
.build.gradle
----
grails {
indy = true
}
----

==== 3. Unified Project Version

Grails 7 moved to a mono repository.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,3 @@ assets {

}

// https://github.com/apache/grails-core/issues/15321
tasks.withType(GroovyCompile).configureEach {
groovyOptions.optimizationOptions.indy = false
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import groovy.transform.CompileStatic
import org.apache.tools.ant.taskdefs.condition.Os
import org.gradle.api.Project
import org.gradle.api.artifacts.dsl.DependencyHandler
import org.gradle.api.provider.Property
import org.gradle.util.internal.ConfigureUtil

import grails.util.Environment
Expand All @@ -42,6 +43,7 @@ class GrailsExtension {
GrailsExtension(Project project) {
this.project = project
this.pluginDefiner = new PluginDefiner(project)
this.indy = project.objects.property(Boolean).convention(false)
}

/**
Expand Down Expand Up @@ -76,6 +78,18 @@ class GrailsExtension {
*/
boolean micronautAutoSetup = true

/**
* Whether to enable Groovy's invokedynamic (indy) bytecode instruction for dynamic Groovy method dispatch.
* Disabled by default to improve performance (see GitHub issue #15293).
* When enabled, Groovy uses JVM invokedynamic instead of traditional callsite caching.
* To enable invokedynamic in build.gradle: grails { indy = true }
*/
final Property<Boolean> indy

void setIndy(boolean enabled) {
this.indy.set(enabled)
}

DependencyHandler getPlugins() {
if (pluginDefiner == null) {
pluginDefiner = new PluginDefiner(project)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@ class GrailsGradlePlugin extends GroovyPlugin {
private void configureGroovyCompiler(Project project) {
Provider<RegularFile> groovyCompilerConfigFile = project.layout.buildDirectory.file('grailsGroovyCompilerConfig.groovy')

GrailsExtension grailsExtension = project.extensions.findByType(GrailsExtension)

project.tasks.withType(GroovyCompile).configureEach { GroovyCompile c ->
c.outputs.file(groovyCompilerConfigFile)

Expand Down Expand Up @@ -216,6 +218,18 @@ class GrailsGradlePlugin extends GroovyPlugin {
c.groovyOptions.configurationScript = combinedFile
}
}

// Configure indy and log status after evaluation so user's grails { } block has been applied
project.afterEvaluate {
boolean indyEnabled = grailsExtension?.indy?.getOrElse(false) ?: false
project.tasks.withType(GroovyCompile).configureEach { GroovyCompile c ->
c.groovyOptions.optimizationOptions.indy = indyEnabled
}
if (!indyEnabled) {
project.logger.lifecycle('Grails: Groovy invokedynamic (indy) is disabled to improve performance (see issue #15293).')
project.logger.lifecycle(' To enable invokedynamic: grails { indy = true } in build.gradle')
}
}
}

protected Closure<String> getGroovyCompilerScript(GroovyCompile compile, Project project) {
Expand Down
4 changes: 0 additions & 4 deletions grails-profiles/base/skeleton/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,3 @@ tasks.withType(Test).configureEach {
useJUnitPlatform()
}

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