| layout | docs |
|---|---|
| toc_group | native-image |
| link_title | Build Configuration |
| permalink | /reference-manual/native-image/BuildConfiguration/ |
- Embedding a Configuration File
- Configuration File Format
- Memory Configuration for Native Image Build
- Runtime vs Build-Time Initialization
- Assisted Configuration of Native Image Builds
- Building Native Image with Java Reflection Example
- Agent Advanced Usage
Native Image supports a wide range of options to configure a native image build process.
A recommended way to provide configuration is to embed a
native-image.properties file into a project JAR file. The Native Image builder
will automatically pick up all configuration options provided anywhere below the
resource location META-INF/native-image/ and use it to construct
native-image command line arguments.
To avoid a situation when constituent parts of a project are built
with overlapping configurations, it is recommended to use "subdirectories" within
META-INF/native-image. That way a JAR file built from multiple maven projects
cannot suffer from overlapping native-image configurations. For example:
- foo.jar has its configurations in
META-INF/native-image/foo_groupID/foo_artifactID - bar.jar has its configurations in
META-INF/native-image/bar_groupID/bar_artifactID
The JAR file that contains foo and bar will then contain both configurations
without conflicting with one another. Therefore the recommended layout for
storing native image configuration data in JAR files is the following:
META-INF/
└── native-image
└── groupID
└── artifactID
└── native-image.properties
Note that the use of ${.} in a native-image.properties file expands to the
resource location that contains that exact configuration file. This can be
useful if the native-image.properties file wants to refer to resources within
its "subfolder", for example, -H:SubstitutionResources=${.}/substitutions.json.
Always make sure to use the option variants that take resources, i.e., use
-H:ResourceConfigurationResources instead of -H:ResourceConfigurationFiles.
Other options that are known to work in this context are:
-H:DynamicProxyConfigurationResources-H:JNIConfigurationResources-H:ReflectionConfigurationResources-H:ResourceConfigurationResources-H:SubstitutionResources-H:SerializationConfigurationResources
By having such a composable native-image.properties file, building an image does not require any additional arguments specified on command line. It is sufficient to just run the following command:
$JAVA_HOME/bin/native-image -jar target/<name>.jarTo debug which configuration data gets applied for the image building, use native-image --verbose. This will show from where native-image picks up the
configurations to construct the final composite configuration command line
options for the native image builder.
native-image --verbose -jar build/basic-app-0.1-all.jar
Apply jar:file://~/build/basic-app-0.1-all.jar!/META-INF/native-image/io.netty/common/native-image.properties
Apply jar:file://~/build/basic-app-0.1-all.jar!/META-INF/native-image/io.netty/buffer/native-image.properties
Apply jar:file://~/build/basic-app-0.1-all.jar!/META-INF/native-image/io.netty/transport/native-image.properties
Apply jar:file://~/build/basic-app-0.1-all.jar!/META-INF/native-image/io.netty/handler/native-image.properties
Apply jar:file://~/build/basic-app-0.1-all.jar!/META-INF/native-image/io.netty/codec-http/native-image.properties
...
Executing [
<composite configuration command line options for the image builder>
]Typical examples of META-INF/native-image based native image configuration can be found in Native Image configuration examples.
A native-image.properties file is a regular Java properties file that can be
used to specify native image configurations. The following properties are
supported.
Args
Use this property if your project requires custom native-image command line options to build correctly. For example, the native-image-configure-examples/configure-at-runtime-example has Args = --initialize-at-build-time=com.fasterxml.jackson.annotation.JsonProperty$Access in its native-image.properties file to ensure the class com.fasterxml.jackson.annotation.JsonProperty$Access gets initialized at image build time.
JavaArgs
Sometimes it can be necessary to provide custom options to the JVM that runs the
native image builder. The JavaArgs property can be used in this case.
ImageName
This property can be used to specify a user-defined name for the image. If
ImageName is not used, a name gets automatically chosen:
native-image -jar <name.jar>has a default image name<name>native-image -cp ... fully.qualified.MainClasshas a default image namefully.qualified.mainclass
Note that using ImageName does not prevent the user to override the name later via command line. For example, if foo.bar contains ImageName=foo_app:
native-image -jar foo.bargenerates the imagefoo_appbutnative-image -jar foo.bar applicationgenerates the imageapplication
The arguments passed to native-image are evaluated left-to-right. This also
extends to arguments that get passed indirectly via META-INF/native-image
based native image configuration. Suppose you have a JAR file that contains
native-image.properties with Args = -H:Optimize=0. Then by using the
-H:Optimize=2 option after -cp <jar-file> you can override the setting that
comes from the JAR file.
If there is a need to pass some options for every image build unconditionally, for
example, to always generate an image in verbose mode (--verbose), you can
make use of the NATIVE_IMAGE_CONFIG_FILE environment variable.
If it is set to a Java properties file, the Native Image builder will use the
default setting defined in there on each invocation. Write a
configuration file and export
NATIVE_IMAGE_CONFIG_FILE=$HOME/.native-image/default.properties in
~/.bash_profile. Every time native-image gets used, it will implicitly use
the arguments specified as NativeImageArgs, plus the arguments specified on the
command line. Here is an example of a configuration file, saved as
~/.native-image/default.properties:
NativeImageArgs = --configurations-path /home/user/custom-image-configs \
-O1
Native Image by default stores the configuration information in user's home directory -- $HOME/.native-image/.
In order to change the output directory, set the environment variable NATIVE_IMAGE_USER_HOME to a different location. For example:
export NATIVE_IMAGE_USER_HOME= $HOME/.local/share/native-imageThe native image build runs on the Java HotSpot VM and uses the memory management of the underlying platform. The usual Java HotSpot command-line options for garbage collection apply to the native image builder.
During the native image build, the representation of a whole program is created to figure out which classes and methods will be used at run time. It is a computationally intensive process. The default values for memory usage at image build time are:
-Xss10M \
-Xms1G \
These defaults can be changed by passing -J + <jvm option for memory> to the native image builder.
The -Xmx value is computed by using 80% of the physical memory size, but no more than 14G per server.
Providing a larger value for -Xmx on command line is possible, e.g., -J-Xmx26G.
By default, image building uses of up to 32 threads (but not more than the number of processors available). For custom values -H:NumberOfThreads=... can be used.
Check other related options to the native image builder from the native-image --expert-options-all list.
Building your application into a native image allows you to decide which parts of your application should be run at image build time and which parts have to run at image run time.
All class-initialization code (static initializers and static
field initialization) of the application you build an image for is executed
at image run time by default. Sometimes it is beneficial to allow class
initialization code to get executed at image build time for faster startup (e.g.,
if some static fields get initialized to run-time independent data). This can be
controlled with the following native-image options:
--initialize-at-build-time=<comma-separated list of packages and classes>--initialize-at-run-time=<comma-separated list of packages and classes>
In addition to that, arbitrary computations are allowed at build time that can be put into ImageSingletons that are
accessible at image run time. For more information please have a look at Native Image configuration examples.
For more information, continue reading to the Class Initialization in Native Image guide.