[
https://issues.apache.org/jira/browse/GROOVY-12365?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18112463#comment-18112463
]
ASF GitHub Bot commented on GROOVY-12365:
-----------------------------------------
testlens-app[bot] commented on PR #2900:
URL: https://github.com/apache/groovy/pull/2900#issuecomment-5576966564
## ✅ All tests passed ✅
🏷️ Commit: fde22cab3658ee69fa2e0469437bd804e65492da
▶️ Tests: 117746 executed
⚪️ Checks: 32/32 completed
---
_Learn more about TestLens at
[testlens.app/docs](https://testlens.app/docs/features/pr-comment/)._
> native: Ship Groovy's own reachability metadata in the groovy jar
> -----------------------------------------------------------------
>
> Key: GROOVY-12365
> URL: https://issues.apache.org/jira/browse/GROOVY-12365
> Project: Groovy
> Issue Type: Improvement
> Reporter: Paul King
> Priority: Major
>
> Groovy 6 dynamic code runs in a GraalVM native image thanks to the AOT link
> mode (GROOVY-12234), but building the image still requires every user to run
> the {{native-image-agent}} first, purely to capture the reflection and
> resource access Groovy's *own* runtime performs. The Iris example README says
> it plainly: without the recorded metadata the image builds and then fails
> initialising {{GroovySystem}}. Logging frameworks and most libraries solved
> this years ago by shipping their reachability metadata inside the jar
> (log4j-core carries
> {{META-INF/native-image/org.apache.logging.log4j/log4j-core/reflect-config.json}}
> and {{resource-config.json}}); {{native-image}} picks such files up
> automatically from the class path, and the GraalVM Gradle/Maven plugins do
> too. Groovy ships nothing, and the central [GraalVM reachability-metadata
> repository|https://github.com/oracle/graalvm-reachability-metadata] has no
> entry for {{org.apache.groovy:groovy}} either (its {{groovy-all}} entry is
> marked not-for-native-image and points at a {{groovy}} entry that does not
> exist), so plugin users get nothing there as well.
> h3. What the agent records for Groovy itself
> Two unrelated dynamic applications (the Iris deep-learning example and a
> small logging probe, both on GraalVM CE 25.2.4) produce almost the same
> Groovy-owned set: about 180 reflection entries and a handful of resources.
> * Runtime bootstrap types under {{groovy.lang}},
> {{org.codehaus.groovy.runtime}}, {{org.codehaus.groovy.reflection}},
> {{org.codehaus.groovy.vmplugin}}: {{GroovySystem}},
> {{MetaClassRegistryImpl}}, {{Closure}}, {{GString}}, {{GroovyObjectSupport}},
> {{ExpandoMetaClass}}, ranges, {{NullObject}}, the VM plugin, etc.
> * The {{Introspector}} probes the metaclass performs for every class it
> introspects: {{<Type>BeanInfo}} and {{<Type>Customizer}} lookups for each
> Groovy runtime type above (these are lookups of classes that do not exist;
> they still need to be registered so the lookup fails quietly rather than with
> {{MissingReflectionRegistrationError}}).
> * {{org.codehaus.groovy.runtime.dgm$N}} proxy classes (30 to 32 per
> application), loaded by name from {{GeneratedMetaMethod$Proxy.createProxy}}
> when a DGM method is first selected. This set is application dependent: a DGM
> method not exercised during the agent run fails at run time with
> {{ClassNotFoundException: org.codehaus.groovy.runtime.dgm$1175}} (seen when a
> code path was added after the agent run).
> * Resources: {{META-INF/dgminfo}},
> {{META-INF/groovy/org.codehaus.groovy.runtime.ExtensionModule}},
> {{META-INF/services/org.codehaus.groovy.runtime.ExtensionModule}}, plus a
> {{.class}} resource lookup ({{groovy/concurrent/AsyncScope.class}}).
> h3. Proposal
> Ship the Groovy-owned part of that metadata in the {{groovy}} jar under
> {{META-INF/native-image/org.apache.groovy/groovy/}} (and the equivalent for
> modules that need it, e.g. {{groovy-json}}, {{groovy-xml}}), following the
> log4j-core layout, so that a dynamic Groovy application builds with plain
> {{native-image -cp ...}} and no agent step:
> * {{reflect-config.json}} / {{reachability-metadata.json}} with the bootstrap
> types, the {{BeanInfo}} / {{Customizer}} probe names, and the DGM proxies.
> For the proxies the safe choice is to register all of them (about 2,000 small
> classes, all of which are in the jar anyway) rather than a sample, since the
> used set cannot be known ahead of time; alternatively
> {{GeneratedMetaMethod$Proxy}} could stop resolving them by name (e.g. a
> generated switch or a {{MethodHandle}} table), which would remove the entries
> entirely.
> * {{resource-config.json}} for {{META-INF/dgminfo}}, the extension-module
> descriptors and the service files.
> * A {{native-image.properties}} with {{Args}} carrying what the README
> currently asks users to type by hand and what the AOT link mode assumes:
> {{--initialize-at-run-time=org.codehaus.groovy.vmplugin.v8.IndyInterface}}
> (and the other runtime classes that must not be initialised at build time).
> This file is also the one place that can set a build-time system property for
> everybody, which matters for the JUL caller-location workaround documented
> under GROOVY-12354 ({{-Djdk.logger.packages=...}} is captured by a build-time
> static initialiser and ignored at run time).
> The metadata should be generated by the build rather than hand-maintained:
> run the agent over the existing native-image parity corpus (or a small
> dedicated script) as part of the performance/native tests, diff against the
> checked-in files, and fail on drift. Once the jar ships it, an entry in the
> reachability-metadata repository becomes unnecessary (the repository prefers
> jar-embedded metadata), but its dangling {{groovy-all}} replacement should be
> corrected or an {{org.apache.groovy:groovy}} entry added pointing at the
> shipped files.
> h3. Out of scope
> Caller-location accuracy in native images (GraalVM's visible
> MethodHandle-interpreter frames) is tracked under GROOVY-12354's
> documentation and the GraalVM issue; the fatal dynamic call to a
> {{@CallerSensitive}} method and the failing MOP {{super}} call in native
> images have their own issues.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)