codeconsole commented on issue #16176: URL: https://github.com/apache/grails-core/issues/16176#issuecomment-5636465372
## Native image is blocked upstream, on Groovy rather than on hints #16180 adds the module this issue asks for, and @matrei built and ran the binary — the half nobody had done. The result is that **the open question above cannot be settled yet**, for reasons that have nothing to do with `I18nRuntimeHintsProcessor`. Dynamic Groovy does not run in a native image on any released Groovy, whichever way it is compiled: | Compiled | What the image does | |---|---| | without invokedynamic | Groovy classes carry a `CallSiteArray` and define call-site classes as they run, which an image forbids: `UnsupportedFeatureError: Tried to define class` | | with invokedynamic | the runtime linkage invokes `IndyInterface`'s bootstrap method without its `<clinit>` having run, so a `static final` handle is still null: `BootstrapMethodError: NullPointerException` at `IndyInterface.makeBootHandle` | Reproduced by @matrei with a ten-line Groovy hello-world — no Spring, no Grails, metadata from the tracing agent — against both 5.1.2 and 4.0.27, so it is not a Grails metadata gap. Registering every `IndyInterface` method for reflection changes nothing, `--exact-reachability-metadata` reports no missing registration, and `--initialize-at-build-time` fails on image-heap objects. **Two upstream blockers, then:** 1. **[GROOVY-12234](https://issues.apache.org/jira/browse/GROOVY-12234)** — an AOT link mode for indy dispatch. On the Groovy 6 line and in no 5.x release. Grails 8.0.x pins `groovy.version` 5.1.2, whose `IndyInterface` carries neither `aotDispatch` nor the `ensureInitialized` guard that 6.0.0-RC-1 added. Related: GROOVY-12227, and in the unreleased 6.0.0-RC-2 GROOVY-12364/12365/12366 (reachability metadata and `native-image.properties` shipped in the groovy jar). 2. **[oracle/graal#10200](https://github.com/oracle/graal/issues/10200)** — GraalVM's bundled Groovy substitution targets `IndyInterface.invalidateSwitchPoints()`, which Groovy 4+ removed, so `nativeCompile` fails during "Initializing" on the GraalVM 21 line. Fixed in the 25 line. There is a third, inside Grails: `CompilePlugin` defaults `grailsIndy` to `false` for published artifacts, because Groovy 5's indy default is a large runtime regression for dynamic Groovy (#15293). So a *released* Grails 8 could not produce an image even once Groovy and GraalVM are fixed. Its own comment already records Grails 9 / Groovy 6 as where that can flip — the same boundary as blocker 1, which is convenient, but it should be a deliberate decision rather than a coincidence. ## What this means for the issue - The module in #16180 lands with the JVM half in `check` and the native half behind `-PnativeTests`, documented as not passing. It is written so it starts passing when the above land rather than having to be authored then. - **The `registerPattern` vs `registerResourceBundle` question stays open.** It needs a binary to settle, and no binary is buildable from a released toolchain today. - Worth deciding separately, and bigger than this issue: **`configureNativeImage` and the upgrade guide currently imply native image is a Grails 8 capability.** On Groovy 5 it is not one, for any application. Either that wiring is documented as forward-looking, or the claim moves to the release where it is true. Cheapest way to learn when the gap closes, per @matrei: the snapshot canary workflow already rebuilds Grails against a Groovy branch by rewriting `groovy.version`. Running `native-i18n` in that job on GraalVM 25, once 6.0.0-RC-2 ships, would tell us without anyone having to re-derive this. -- 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]
