Class Initialization in Native Image

The semantics of Java requires that a class is initialized the first time it is accessed at runtime. Class initialization has negative consequences for compiling Java applications ahead-of-time for the following two reasons:

To reduce the negative impact of class initialization, Native Image supports class initialization at build time: it can initialize classes when it builds an executable, making runtime initialization and checks unnecessary. All the static state from initialized classes is stored in the executable. Access to a class’s static fields that were initialized at build time is transparent to the application and works as if the class was initialized at runtime.

However, Java class initialization semantics impose several constraints that complicate class initialization policies, such as:

To enjoy the complete out-of-the-box experience of Native Image and still get the benefits of build-time initialization, Native Image does two things:

To track which classes were initialized and why, pass the command-line option -H:+PrintClassInitialization to the native-image tool. This option helps you configure the native image builder to work as required. The goal is to have as many classes as possible initialized at build time, yet keep the correct semantics of the application.

Build-Time Initialization

Native Image initializes most JDK classes at build time, including the garbage collector, important JDK classes, and the deoptimizer. For all of the classes that are initialized at build time, Native Image gives proper support so that the semantics remain consistent despite class initialization occurring at build time. If you discover an issue with a JDK class behaving incorrectly because of class initialization at build time, please report an issue.

Automatic Initialization of Safe Classes

For application classes, Native Image tries to find classes that can be safely initialized at build time. A class is considered safe if all of its relevant supertypes are safe and if the class initializer does not call any unsafe methods or initialize other unsafe classes.

A method is considered unsafe if:

A test that shows examples of classes that are proven safe can be found here. The list of all classes that are proven safe is output to a file via the -H:+PrintClassInitialization command-line option to the native-image tool.

Note: You can also Specify Class Initialization Explicitly.