[ 
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)

Reply via email to