codeconsole opened a new issue, #16752:
URL: https://github.com/apache/grails-core/issues/16752
To start in a native image without recorded metadata, the framework
registers the constructors of every Groovy enum it finds for reflection
(`BytecodeRuntimeHints`, added in #16180). It has to, because Groovy creates an
enum's constants through the synthetic `$INIT` helper, and the meta class picks
the constructor by reflecting over the declared constructors. Without the
registration, `grails.util.Environment` fails before Spring starts with "Could
not find matching constructor".
Groovy is removing that need for most enums:
- **Groovy 6.0.0** already calls the `(String,int)` constructor directly
when every constant is a plain identifier (GROOVY-12240).
- **apache/groovy#3024** extends the direct call to constants whose
arguments are literals, such as `PRIVATE('private')`, when exactly one
constructor can take them unchanged.
## What to change once a Groovy release with apache/groovy#3024 is in use
- [ ] In `BytecodeRuntimeHints`, register constructors only for Groovy enums
whose static initializer still calls `$INIT`. That is a check of `<clinit>` for
a call to `$INIT` (an `invokestatic`, or an invokedynamic whose bootstrap name
is `$INIT`), not every class that extends `Enum` and implements `GroovyObject`.
- [ ] Update the enum bullet in `BytecodeRuntimeHints`' javadoc and the
matching bullet in `deploymentAot.adoc` ("creating a Groovy enum's constants").
They should say that only enums Groovy still creates through `$INIT` are
registered.
- [ ] Build the native-i18n image and run its checks: `./gradlew
:native-i18n:check -PnativeTests` from `end-to-end`, with a GraalVM `JAVA_HOME`.
On native-i18n's classpath today:
| Enum | Constants | On Groovy 6.0.0 | With apache/groovy#3024 |
|---|---|---|---|
| `grails.util.Environment` | plain identifiers | still `$INIT` (see note) |
still `$INIT` (see note) |
| `FieldDefinition.AccessModifier` | one String literal each | `$INIT` |
direct |
| `GrailsInterceptorHandlerInterceptorAdapter.Phase` | one String literal
each | `$INIT` | direct |
| `ConstraintStyle`, `GrailsBanner`'s three version options, `DisplayType`,
`MultiTenancyMode` | plain identifiers | direct | direct |
`grails.util.Environment` needs its registration regardless. Its constants
are plain identifiers, but `grails-gradle-model` is compiled by Gradle's Groovy
4, which predates GROOVY-12240. The `<clinit>` check keeps it registered
without special-casing it.
The narrowing can also be done before the Groovy release, since it only
stops registering enums that no longer need it. The release is what moves the
two literal-argument enums off the list.
## Groovy version
apache/groovy#3024 targets Groovy master (7.0.0-SNAPSHOT). Grails 9 builds
with Groovy 6.0.x, so it only benefits once the change is backported to
`GROOVY_6_0_X`; the PR asks for that.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]