Skip to content

Merge 8.1.x into 9.0.x - #16319

Open
jamesfredley wants to merge 16 commits into
9.0.xfrom
merge/8.1.x-into-9.0.x
Open

Merge 8.1.x into 9.0.x#16319
jamesfredley wants to merge 16 commits into
9.0.xfrom
merge/8.1.x-into-9.0.x

Conversation

@jamesfredley

Copy link
Copy Markdown
Contributor

Description

Merge the pending 8.0.x -> 8.1.x line (#16318) into 9.0.x so Grails 9 receives #16178 (CompilePlugin invokedynamic default) and the related 8.0 groovydoc/CI heap work.

This is a release-line merge, not a squash. Stacked on #16318 (merge/8.0.x-into-8.1.x). One conflict in gradle.properties was resolved by keeping 9.0.x projectVersion=9.0.0-SNAPSHOT and the Spock Groovy 6 version-check JVM arg, and carrying the 8.0 daemon-heap comments.

CompilePlugin auto-merged: Grails 8 indy-off default plus 9.0.x Spock disableGroovyVersionCheck fork args. #16165 will flip that CompilePlugin default to indy-on for Grails 9.

Contributor Checklist

Issue and Scope

  • This PR is linked to an existing issue that has been acknowledged or approved by the project team. If no approved issue exists, please give background on why this change is necessary. Tickets are preferred for release change log history.
  • This PR addresses the complete scope of the linked issue. Partial implementations or unfinished work should not be submitted for review.
  • This PR contains a single, focused change. Unrelated changes should be submitted as separate pull requests.
  • This PR targets the correct branch for the type of change:
    • Patch release branches (e.g., 7.0.x): Bug fixes only. No new features or API changes.
    • Minor release branches (e.g., 7.1.x): New features are welcome, but breaking existing APIs must be avoided.
    • Major release branches (e.g., 8.0.x): Reserved for major changes. Breaking API changes are permitted.

Code Quality

  • I have added or updated tests that cover the changes introduced in this PR. All code contributions are expected to include appropriate test coverage.
  • I have verified that all existing tests pass by running ./gradlew build --rerun-tasks.
  • My code follows the project's code style guidelines. I have run ./gradlew codeStyle and resolved any violations. See Code Style for details.
  • This PR does not include mass reformatting, style-only changes, or large-scale refactoring unless it was explicitly approved in the linked issue. Unsolicited reformatting will not be accepted.
  • If generative AI tooling was used in preparing this contribution, a quality model was used to ensure contributions are consistent with the project's quality standards.

Licensing and Attribution

Documentation

  • If this PR introduces user-facing changes, I have included or updated the relevant documentation.
  • If this PR adds a new feature, I have updated the What's New section of the Grails Guide.
  • If this PR introduces breaking changes or changes that require user action during an upgrade, I have updated the Upgrade Notes for the corresponding version in the Grails Guide.
  • The PR description clearly explains what was changed and why.

Generative AI (Cursor Grok 4.6) was used to complete the merge and resolve the gradle.properties conflict.

org.gradle.jvmargs sizes the Gradle daemon only. Test forks are separate
child JVMs that take their heap from maxHeapSize in gradle/test-config.gradle,
so a job's configured heap is the daemon -Xmx plus the concurrent test forks
times the per-fork heap. Those two numbers live in different files and have
never been reasoned about together.

The concurrent fork count is not maxParallelForks. With org.gradle.parallel=true
several Test tasks run at once, so the live JVM count is bounded by Gradle's
global worker pool, which defaults to the CPU count. On the 4-CPU, ~16 GB Linux
and Windows runners that floor is 5G + 4x768m = 8G and fits. On the 3-CPU,
~7 GB macOS runner it is 5G + 3x768m = 7.25G and does not.

Cap --max-workers on the macOS leg, since that is what actually limits
concurrent test and compiler JVMs, and keep maxTestParallel alongside it so no
single task exceeds the same cap. Both are passed through a new runner_arguments
matrix key that is undefined, and therefore empty, for every other entry.

The daemon stays at 5 GB: groovydoc is what needs it, and shrinking it would
trade a memory problem for a slower build. Document the arithmetic next to
org.gradle.jvmargs as a simplified configured-heap floor, explicitly excluding
metaspace, native memory and the forked compiler workers that CompilePlugin
gives their own -Xmx2G, so it is not mistaken for a true peak.

This changes concurrency only. No test is added, removed, skipped or weakened.

Assisted-by: claude-code:claude-opus-5
Groovy 5 defaults indy on. Only modules that apply the Grails Gradle
plugin inherited grails.indy=false, so published framework artifacts
were mixed. Centralize indy=false in CompilePlugin and apply
gradle/groovy-indy.gradle from the grails-core, grails-gradle, and
grails-forge builds. CI can still opt in with -PgrailsIndy=true.

See #15293

Assisted-by: Sisyphus:grok-4.6
With indy off, log.debug inside GormStaticApi.count()'s session
callback was dispatched as Domain.debug(...). Capture the @slf4j
logger in a local first. Also trim -PgrailsIndy the same way as
CompilePlugin and apply the shared groovy-indy script from
build-logic.

Assisted-by: Sisyphus:grok-4.6
Class.newInstance(Map) is not selected under @CompileStatic when
invokedynamic is disabled. Use InvokerHelper.invokeConstructorOf with
an explicit Object[] so nested Map-constructor types still bind.
Also avoid `null as boolean` in the Map-constructor test fixture,
which Groovy 5 throws on without indy after unbindable properties
are filtered from constructor arguments.

Assisted-by: Sisyphus:grok-4.6
Honor review: drop groovy-indy.gradle and subprojects applies. Unpublished build-logic uses Gradle's Groovy default.
Hibernate 7 publishes jboss-logging as a runtime-only transitive.
Groovydoc Class.forName's referenced types, so
:grails-data-hibernate7-dbmigration-core:groovydoc failed in CI
(Forge/e2e publish) with NoClassDefFoundError: org/jboss/logging/Logger.
build(ci): bound concurrent JVMs on the macOS runner
build: disable Groovy invokedynamic for the Grails 8 compile
Copilot AI lite review requested due to automatic review settings September 4, 2026 23:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

This is a cross-branch release-line merge touching build logic and CI behavior, which warrants final human review despite the changes appearing internally consistent.

Pull request overview

Release-line merge bringing the 8.1.x line’s pending build/runtime fixes into 9.0.x, primarily around Groovy invokedynamic (indy) defaults, databinding Map-constructor behavior under @CompileStatic when indy is disabled, and build/docs/CI stability improvements.

Changes:

  • Fix Map-constructor instantiation for nested databinding under @CompileStatic by bypassing Class.newInstance(Map) and invoking the Map constructor reliably.
  • Prevent @Slf4j logger calls inside a session callback from being mis-dispatched (when indy is off) by capturing the logger before entering the closure; add regression coverage.
  • Improve build robustness: centralize indy default in CompilePlugin with whitespace-tolerant parsing, extend Groovydoc classpath to include runtime deps, and reduce macOS CI memory pressure via --max-workers.
File summaries
File Description
grails-web-databinding/src/main/groovy/grails/web/databinding/GrailsWebDataBinder.groovy Uses the new Map-constructor instantiation helper to keep nested binding working under indy-off + @CompileStatic.
grails-test-suite-persistence/src/test/groovy/grails/web/databinding/GrailsWebDataBinderSpec.groovy Avoids null as boolean failure under indy-off in a Map-constructor test fixture.
grails-datamapping-core/src/test/groovy/org/grails/datastore/gorm/GormStaticApiSpec.groovy Adds regression test ensuring count() doesn’t fail due to logger dispatch issues under indy-off.
grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/GormStaticApi.groovy Captures the SLF4J logger before entering the callback closure to avoid methodMissing/dynamic-finder dispatch.
grails-databinding-core/src/main/groovy/grails/databinding/SimpleDataBinder.groovy Introduces newInstanceFromMapArguments(...) using InvokerHelper to reliably invoke Map constructors under @CompileStatic.
gradle/grails-extension-gradle-config.gradle Makes -PgrailsIndy=... parsing whitespace-tolerant and documents alignment with CompilePlugin.
gradle.properties Adds detailed daemon/test-fork heap budgeting commentary to clarify CI sizing constraints.
build-logic/plugins/src/test/groovy/org/apache/grails/buildsrc/GroovydocEnhancerPluginSpec.groovy New test ensuring Groovydoc classpath includes runtime-only jars required for Class.forName resolution.
build-logic/plugins/src/test/groovy/org/apache/grails/buildsrc/CompilePluginSpec.groovy Adds TestKit coverage for default indy=false and -PgrailsIndy opt-in (including whitespace trimming).
build-logic/plugins/src/main/groovy/org/apache/grails/buildsrc/GroovydocEnhancerPlugin.groovy Extends Groovydoc classpath with runtimeClasspath to prevent NoClassDefFoundError during doc generation.
build-logic/plugins/src/main/groovy/org/apache/grails/buildsrc/CompilePlugin.groovy Sets GroovyCompile indy default via lookupProperty(...) and documents the Grails 8/9 intent.
.github/workflows/gradle.yml Caps macOS runner concurrency (--max-workers=2) to reduce memory pressure while keeping groovydoc viable.
Review details
  • Files reviewed: 12/12 changed files
  • Comments generated: 0
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@codecov

codecov Bot commented Sep 4, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 30.1177%. Comparing base (51b1528) to head (92e2c82).

Additional details and impacted files

Impacted file tree graph

@@              Coverage Diff              @@
##                9.0.x     #16319   +/-   ##
=============================================
  Coverage     30.1177%   30.1177%           
  Complexity        519        519           
=============================================
  Files              83         83           
  Lines            4758       4758           
  Branches          815        815           
=============================================
  Hits             1433       1433           
  Misses           3082       3082           
  Partials          243        243           
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@testlens-app

testlens-app Bot commented Sep 4, 2026

Copy link
Copy Markdown

✅ All tests passed ✅

🏷️ Commit: 92e2c82
▶️ Tests: 7000 executed
⚪️ Checks: 85/85 completed


Learn more about TestLens at testlens.app/docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants