fix: add Java 23+/24+ compatibility JVM args and upgrade commons-lang3 to 3.20.0#15417
Merged
jdaugherty merged 5 commits into7.0.xfrom Feb 21, 2026
Merged
fix: add Java 23+/24+ compatibility JVM args and upgrade commons-lang3 to 3.20.0#15417jdaugherty merged 5 commits into7.0.xfrom
jdaugherty merged 5 commits into7.0.xfrom
Conversation
…3 to 3.20.0 Add version-conditional JVM arguments in GrailsGradlePlugin to suppress warnings on modern JDKs: - --sun-misc-unsafe-memory-access=allow for Java 23+ (JEP 471/498, #15343) - --enable-native-access=ALL-UNNAMED for Java 24+ (JEP 472, #15216) Override commons-lang3 from 3.17.0 (Spring Boot managed) to 3.20.0 in the Grails BOM to fix LANG-1786 timezone warnings and CVE-2025-48924. Includes Gradle TestKit functional tests verifying the args are applied correctly based on toolchain version. Assisted-by: Claude Code <Claude@Claude.ai>
Tests were hardcoding expected values for JDK 17 but CI also runs on Java 25 where both compat flags are correctly applied. Compute expected values dynamically from CURRENT_JDK. Assisted-by: Claude Code <Claude@Claude.ai>
Contributor
There was a problem hiding this comment.
Pull request overview
This pull request adds Java 23+ and 24+ compatibility by configuring JVM arguments to suppress warnings from deprecated APIs and native access restrictions. It also upgrades commons-lang3 from 3.17.0 to 3.20.0 to fix timezone deprecation warnings and a security vulnerability.
Changes:
- Added version-conditional JVM argument configuration in
GrailsGradlePluginto suppress Java 23+sun.misc.Unsafewarnings and Java 24+ native access warnings - Upgraded commons-lang3 to 3.20.0 in the Grails BOM to fix LANG-1786 (timezone ID deprecation) and CVE-2025-48924
- Comprehensive Gradle TestKit functional tests for JVM argument configuration with multiple toolchain scenarios
Reviewed changes
Copilot reviewed 15 out of 19 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/core/GrailsGradlePlugin.groovy | Added configureJavaCompatibilityArgs() method to conditionally apply JVM flags based on target Java version, plus helper method resolveTargetJavaVersion() and new imports |
| dependencies.gradle | Added commons-lang3 3.20.0 version override in BOM to supersede Spring Boot's managed 3.17.0 |
| grails-gradle/plugins/src/test/groovy/org/grails/gradle/plugin/core/GrailsGradlePluginJavaCompatSpec.groovy | New test spec with 4 test cases covering no-toolchain, current-toolchain, Java 23, and Java 24 scenarios |
| grails-gradle/plugins/src/test/resources/test-projects/java-compat-* | Four test fixture projects for functional testing of JVM arg configuration |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
jdaugherty
previously requested changes
Feb 20, 2026
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/GrailsGradlePlugin.groovy
Outdated
Show resolved
Hide resolved
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/GrailsGradlePlugin.groovy
Show resolved
Hide resolved
…r review
Address review feedback from jdaugherty:
- Replace afterEvaluate anti-pattern with project.plugins.withId('java')
- Move version resolution into configureEach callbacks so toolchain
config is read lazily after build script evaluation
- Add project.logger.info for each JVM compatibility flag added
Assisted-by: Claude Code <Claude@Claude.ai>
jdaugherty
approved these changes
Feb 21, 2026
grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/core/GrailsGradlePlugin.groovy
Outdated
Show resolved
Hide resolved
…ainForForkTasks
Use plugins.withId('java') with configureEach instead of
afterEvaluate, matching the pattern used by
configureJavaCompatibilityArgs. The configureEach closure defers
execution until task realization (after evaluation), so the
toolchain check works without afterEvaluate.
Assisted-by: Claude Code <Claude@Claude.ai>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
GrailsGradlePluginto suppress warnings on Java 23+ and 24+commons-lang3from 3.17.0 (Spring Boot managed) to 3.20.0 in the Grails BOMChanges
1. Java compatibility JVM args in
GrailsGradlePlugin(#15216, #15343)Adds
configureJavaCompatibilityArgs(Project)which conditionally applies JVM flags to allTestandJavaExectasks based on the target Java version (toolchain-aware, falls back to current JVM):--sun-misc-unsafe-memory-access=allowsun.misc.Unsafe.allocateMemoryfor off-heap buffers. Terminal deprecation warnings appear on 23+. Suppresses until Netty migrates toMemorySegment(Netty 4.2+).--enable-native-access=ALL-UNNAMEDSystem.loadLibrary/native methods. Warning-only now, becomes mandatory deny in a future JDK.Flags are not added on Java 17-22, avoiding
Unrecognized optionerrors.Implementation approach: Uses
project.plugins.withId('java')with lazyconfigureEachcallbacks so toolchain configuration is read after build script evaluation. Each flag logs atINFOlevel when added (e.g.Grails: adding --enable-native-access=ALL-UNNAMED to test for Java 25 compatibility).Note on #15343: The original issue suggested
--add-opens=java.base/sun.misc=ALL-UNNAMED, but that flag addresses module visibility, not thesun.misc.Unsafememory-access deprecation. The correct flag is--sun-misc-unsafe-memory-access=allow.2. commons-lang3 BOM override to 3.20.0 (#15045)
Spring Boot 3.5.x manages commons-lang3 at 3.17.0, which has two issues:
FastDatePrinteruses deprecated three-letter timezone IDs (e.g.PST,CST,EST), causing a flood ofWARNING: Use of the three-letter time zone ID "XYZ" is deprecatedmessages on Java 25StackOverflowErrorinClassUtils.getClasswith crafted input (fixed in 3.18.0+)Non-breaking changes analysis (3.17.0 -> 3.20.0)
All versions in this range require Java 8+ (unchanged baseline). There are no breaking changes:
LocaleUtils.toLocale()now accepts 2-letter country codes it previously rejected (more lenient, not breaking)StringUtils,ArrayUtils,ClassUtils, etc. - purely additive3. Tests
New
GrailsGradlePluginJavaCompatSpecwith 4 Gradle TestKit functional tests:--sun-misc-unsafe-memory-access=allowTestandJavaExectasksFiles Changed
grails-gradle/plugins/.../GrailsGradlePlugin.groovy- AddedconfigureJavaCompatibilityArgs(),applyCompatArgs(),resolveTargetJavaVersion(), new importsdependencies.gradle- Addedcommons-lang3.version: 3.20.0andcommons-lang3BOM entrygrails-gradle/plugins/.../GrailsGradlePluginJavaCompatSpec.groovy- New test specgrails-gradle/plugins/.../test-projects/java-compat-*- 4 new test fixture projectsRelated Issues