[
https://issues.apache.org/jira/browse/GROOVY-12366?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Paul King updated GROOVY-12366:
-------------------------------
Description:
Companion to GROOVY-12365 (which covers the reflection and resource metadata).
GraalVM's {{native-image}} reads a {{native-image.properties}} file from any
jar on the class path at
{{META-INF/native-image/<groupId>/<artifactId>/native-image.properties}}; its
{{Args}} line is appended to the build's command line, and the GraalVM Gradle
and Maven plugins honour it too. It is the one place a library can state the
build arguments it needs so that users do not have to discover them. Groovy
currently ships none, and projects that build native images of dynamic Groovy
code end up carrying Groovy's requirements in their own build files, for
example:
{code}
buildArgs.add('--initialize-at-run-time=org.codehaus.groovy.control.XStreamUtils,groovy.grape.GrapeIvy,org.codehaus.groovy.vmplugin.v8.IndyInterface')
buildArgs.add('-H:IncludeResources=META-INF/dgminfo')
buildArgs.add('-H:IncludeResources=META-INF/groovy/.*')
buildArgs.add('-H:IncludeResources=META-INF/services/.*')
{code}
h3. Proposal
Add {{META-INF/native-image/org.apache.groovy/groovy/native-image.properties}}
to the {{groovy}} jar with:
* {{--initialize-at-run-time}} for the runtime classes that must not be
initialised at image build time. Recent GraalVM releases default application
classes to run-time initialisation, but the analysis may still simulate an
initialiser it can prove side-effect free, and Groovy's own code notes the
hazard: {{AotDispatch}} avoids caching its AOT decision in a static precisely
because "under native image this class may be initialized at image build time",
and {{HiddenClassDefiner.isEnabled()}} only checks for the run-time marker, so
a build-time initialisation of {{IndyInterface}} would attempt hidden-class
definition inside the image builder. Pinning
{{org.codehaus.groovy.vmplugin.v8.IndyInterface}},
{{org.apache.groovy.runtime.indy.AotDispatch}},
{{org.apache.groovy.util.HiddenClassDefiner}} and the other property-reading
runtime classes makes the AOT link mode's assumptions explicit instead of
relying on the default. Classes that historically needed it ({{XStreamUtils}},
{{GrapeIvy}}) should be reviewed rather than copied blindly, since the Iris
README already found the blanket flags unnecessary on GraalVM 25.
* Nothing for resources once GROOVY-12365 ships {{resource-config.json}}; until
then the three {{-H:IncludeResources}} patterns above belong here so the two
issues can land independently.
Things that should *not* go in the file, and why:
* {{-Djdk.logger.packages=...}}. GROOVY-12354 documents that
{{java.util.logging}} caller inference in a native image only works if this
property is passed at image build time (it is captured by a build-time static
initialiser). The properties file is technically the only place Groovy could
set it for everyone, but the property is a single comma-separated value, so a
later {{-D}} from another jar or the user's own build replaces it wholesale
rather than merging. Setting it from a library would silently break other
libraries' lists. Keep it documented as a user choice; at most ship the
recommended value as a comment in the file.
* {{--initialize-at-build-time}} for anything: the Iris README records the
failures that causes (runtime state in the image heap, e.g. seeded {{Random}}
instances), and AOT link mode expects run-time initialisation.
* {{-H:ConfigurationFileDirectories}} or application-specific reflection: that
is the user's audit, which composes with whatever the jar ships.
h3. Verification
Build the existing native-image sample (or the small corpus proposed in
GROOVY-12365) with plain {{native-image -cp groovy.jar:app ...}} and no extra
arguments, on the GraalVM versions the project claims to support, and assert it
links and runs. Also confirm
{{--trace-class-initialization=org.codehaus.groovy.vmplugin.v8.IndyInterface}}
reports run-time initialisation, which is the observable guarantee this file
provides.
> native: add a native-image.properties file
> ------------------------------------------
>
> Key: GROOVY-12366
> URL: https://issues.apache.org/jira/browse/GROOVY-12366
> Project: Groovy
> Issue Type: Improvement
> Reporter: Paul King
> Priority: Major
>
> Companion to GROOVY-12365 (which covers the reflection and resource
> metadata). GraalVM's {{native-image}} reads a {{native-image.properties}}
> file from any jar on the class path at
> {{META-INF/native-image/<groupId>/<artifactId>/native-image.properties}}; its
> {{Args}} line is appended to the build's command line, and the GraalVM Gradle
> and Maven plugins honour it too. It is the one place a library can state the
> build arguments it needs so that users do not have to discover them. Groovy
> currently ships none, and projects that build native images of dynamic Groovy
> code end up carrying Groovy's requirements in their own build files, for
> example:
> {code}
> buildArgs.add('--initialize-at-run-time=org.codehaus.groovy.control.XStreamUtils,groovy.grape.GrapeIvy,org.codehaus.groovy.vmplugin.v8.IndyInterface')
> buildArgs.add('-H:IncludeResources=META-INF/dgminfo')
> buildArgs.add('-H:IncludeResources=META-INF/groovy/.*')
> buildArgs.add('-H:IncludeResources=META-INF/services/.*')
> {code}
> h3. Proposal
> Add
> {{META-INF/native-image/org.apache.groovy/groovy/native-image.properties}} to
> the {{groovy}} jar with:
> * {{--initialize-at-run-time}} for the runtime classes that must not be
> initialised at image build time. Recent GraalVM releases default application
> classes to run-time initialisation, but the analysis may still simulate an
> initialiser it can prove side-effect free, and Groovy's own code notes the
> hazard: {{AotDispatch}} avoids caching its AOT decision in a static precisely
> because "under native image this class may be initialized at image build
> time", and {{HiddenClassDefiner.isEnabled()}} only checks for the run-time
> marker, so a build-time initialisation of {{IndyInterface}} would attempt
> hidden-class definition inside the image builder. Pinning
> {{org.codehaus.groovy.vmplugin.v8.IndyInterface}},
> {{org.apache.groovy.runtime.indy.AotDispatch}},
> {{org.apache.groovy.util.HiddenClassDefiner}} and the other property-reading
> runtime classes makes the AOT link mode's assumptions explicit instead of
> relying on the default. Classes that historically needed it
> ({{XStreamUtils}}, {{GrapeIvy}}) should be reviewed rather than copied
> blindly, since the Iris README already found the blanket flags unnecessary on
> GraalVM 25.
> * Nothing for resources once GROOVY-12365 ships {{resource-config.json}};
> until then the three {{-H:IncludeResources}} patterns above belong here so
> the two issues can land independently.
> Things that should *not* go in the file, and why:
> * {{-Djdk.logger.packages=...}}. GROOVY-12354 documents that
> {{java.util.logging}} caller inference in a native image only works if this
> property is passed at image build time (it is captured by a build-time static
> initialiser). The properties file is technically the only place Groovy could
> set it for everyone, but the property is a single comma-separated value, so a
> later {{-D}} from another jar or the user's own build replaces it wholesale
> rather than merging. Setting it from a library would silently break other
> libraries' lists. Keep it documented as a user choice; at most ship the
> recommended value as a comment in the file.
> * {{--initialize-at-build-time}} for anything: the Iris README records the
> failures that causes (runtime state in the image heap, e.g. seeded {{Random}}
> instances), and AOT link mode expects run-time initialisation.
> * {{-H:ConfigurationFileDirectories}} or application-specific reflection:
> that is the user's audit, which composes with whatever the jar ships.
> h3. Verification
> Build the existing native-image sample (or the small corpus proposed in
> GROOVY-12365) with plain {{native-image -cp groovy.jar:app ...}} and no extra
> arguments, on the GraalVM versions the project claims to support, and assert
> it links and runs. Also confirm
> {{--trace-class-initialization=org.codehaus.groovy.vmplugin.v8.IndyInterface}}
> reports run-time initialisation, which is the observable guarantee this file
> provides.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)