public class NativeImageMetadataGenerator
extends Object
Writes the GraalVM reachability metadata for Groovy's own runtime into the
groovy jar, as META-INF/native-image/org.apache.groovy/groovy/reachability-metadata.json
(GROOVY-12365), so that a dynamic Groovy application builds with plain
native-image and no agent step for anything the runtime does
on its own behalf.
Every entry is derived from what the runtime is known to do, rather than recorded by observing an application, and is conditional on the class that performs the access being reached (the metaclass registry, or the invokedynamic bootstrap), so a statically compiled program that links no dynamic call site carries none of it:
IndyInterface).
Its classes obtain method handles to their own methods and to a few JDK and
MOP methods through a Lookup held in a run-time-initialised class,
which the image builder cannot fold, so the targets are registered.getDefaultImportClasses loads GroovySystem and
groovy.beans.ListenerList by name to locate the groovy jar; those
names are not constant Class.forName arguments the image builder
can fold.CachedClass reads their declared constructors, methods
and fields, up the superclass chain, and the JDK's Introspector their public
methods; every interface in the hierarchy is cached and SAM-checked. The
types are the Groovy-owned DGM receivers and the runtime classes an ordinary
dynamic program instantiates, such as its closure and range
implementations.<Type>BeanInfo and <Type>Customizer (the
Introspector) and groovy.runtime.metaclass.<Type>MetaClass (the
registry's custom metaclass lookup). Registering the absent names makes the
lookups fail with the ClassNotFoundException the callers expect
rather than a missing-registration error.--exact-reachability-metadata.
The tests-native subproject checks all of this against a probe
program: its checkNativeMetadata task fails on any Groovy-owned need
the native-image agent records that is not shipped, and its nativeRun
tasks build and run the probe as an image with nothing but this metadata for
Groovy's part.
Not emitted, deliberately: Class.forName calls with a constant name
(the image builder folds them, absent classes included); reflection over
the application's classes and the JDK types it uses dynamically; dynamic
proxies for closures coerced to interfaces; serialization. Those depend on
what the application does and remain the application's, or the
native-image agent's, responsibility.
| Modifiers | Name | Description |
|---|---|---|
static String |
METADATA_DIRECTORY |
The metadata directory inside the jar, per the GraalVM convention META-INF/native-image/<groupId>/<artifactId>/. |
static String |
METADATA_FILE |
| Type Params | Return Type | Name and description |
|---|---|---|
|
public static void |
main(String[] args)The build's entry point for a module: <artifactId> <targetDirectory> <extensionClasses> <staticExtensionClasses>,
the class lists comma-separated and possibly empty. |
|
public static String |
write(List<GeneratedMetaMethod.DgmMethodRecord> records, String targetDirectory)Writes the metadata file under targetDirectory. |
|
public static String |
writeForModule(String artifactId, List<Class<?>> instanceExtensions, List<Class<?>> staticExtensions, String targetDirectory)Writes the metadata of an extension module (a jar with a META-INF/groovy/org.codehaus.groovy.runtime.ExtensionModule
descriptor) under targetDirectory, as
META-INF/native-image/org.apache.groovy/<artifactId>/reachability-metadata.json.
|
The metadata directory inside the jar, per the GraalVM convention META-INF/native-image/<groupId>/<artifactId>/.
The build's entry point for a module:
<artifactId> <targetDirectory> <extensionClasses> <staticExtensionClasses>,
the class lists comma-separated and possibly empty. The classes are
loaded without initialisation, so no Groovy runtime starts here.
Writes the metadata file under targetDirectory.
records - the DGM records DgmConverter producedtargetDirectory - the classes directory the jar is assembled from Writes the metadata of an extension module (a jar with a
META-INF/groovy/org.codehaus.groovy.runtime.ExtensionModule
descriptor) under targetDirectory, as
META-INF/native-image/org.apache.groovy/<artifactId>/reachability-metadata.json.
The registry loads the descriptor's extension classes by name, scans
their static methods and caches every type in those signatures, all
while it bootstraps; the entries are conditional on the registry.
artifactId - the module's artifact id, e.g. groovy-nioinstanceExtensions - the descriptor's extensionClassesstaticExtensions - the descriptor's staticExtensionClassestargetDirectory - the directory the jar is assembled from