Native Image

The Native Image component of GraalVM Enterprise allows to compile a JVM-based application ahead-of-time under closed-world assumption into an executable image or a shared object (ELF-64 or 64-bit Mach-O), called a native image.

The input is Java bytecode, compiled from any JVM language. The entire process that produces a native image is image build time to clearly distinguish it from the compilation of Java source code to bytecode. The Native Image builder or native-image is a Java application that processes all the classes of an application and its dependencies, dependent JDK libraries and VM components. It statically analyses that data to determine which classes and methods are reachable and used during application execution. Then it passes all this reachable code as the input to the GraalVM compiler which ahead-of-time compiles it to a native executable for a specific operating system and architecture.

Install Native Image

Native Image is distributed as a separate installable and can be added to GraalVM Enterprise with the GraalVM Updater tool. Download the Native Image component from Oracle Technology Network. You must accept the License Agreement before downloading. Then install Native Image from the JAR file:

Optionally, you can install Native Image from a local components collection:

gu install -C /path/to/downloads/directory native-image

When installing components from a given directory, you can allow installing all components which have a correct version number for GraalVM Enterprise using wildcards:

gu install -C ~/Download/Components/ native*

After this additional step, the native-image executable will become available in the bin directory.

Build Native Image

To build an image for a class in the current working directory, use:

native-image [options] class [imagename] [options]

To build an image for a jar file, use:

native-image [options] -jar jarfile [imagename] [options]

The native-image command needs to provide the class path for all classes using the familiar option from the java launcher: -cp followed by a list of directories or .jar files, separated by :. The name of the class containing the main method is the last argument, or you can use -jar and provide a .jar file that specifies the main method in its manifest.

GraalVM native-image supports JVM-based languages, e.g., Java, Scala, Kotlin. The resulting native image can, optionally, execute dynamic languages like Ruby, R, or Python, but it does not pre-compile their code itself. Polyglot embeddings can also be compiled ahead-of-time. To inform native-image of guest languages used by an application, specify --language:<languageId> for each guest language used (e.g., --language:js).

Prerequisites

For compilation native-image depends on the local toolchain, so please make sure: glibc-devel, zlib-devel (header files for the C library and zlib) and gcc are available on your system. For Linux platform, install libstdc++ dependency additionally. For instance, on Oracle Linux run:

yum install libstdc++-static`

Another prerequisite to consider is the maximum heap size. Physical memory for running a JVM-based application may be insufficient to build a native image. For server-based image building, it is allowed to use 80% of the reported physical RAM for all servers together, but never more than 14GB per server (for exact details please consult the native-image source code). If you run with --no-server option, you will get the whole 80% of what is reported as physical RAM as the baseline. This mode respects -Xmx arguments additionally.

Prerequisites for Using Native Image on Windows

To make use of Native Image on Windows, follow the further recommendations. The required Microsoft Visual C++ (MSVC) version depends on the JDK version that GraalVM is based on. For GraalVM Enterprise distribution based on JDK 8, you will need MSVC 2010 SP1 version. The recommended installation method is using Microsoft Windows SDK 7.1:

  1. Download the SDK file GRMSDKX_EN_DVD.iso for from Microsoft.
  2. Mount the image by opening F:\Setup\SDKSetup.exe directly.

For GraalVM Enterprise distribution based on JDK 11, you will need MSVC 2017 15.5.5 or later version.

The last prerequisite, common for both GraalVM distribution based on JDK 11 and JDK 8, is the proper Developer Command Prompt for your version of Visual Studio. Namely, it is should be theĀ x64 Native Tools Command Prompt. Use Visual Studio 2017 or later.

How to Determine What Version of GraalVM a Native Image is Generated with

Assuming you have a Java class file EmptyHello.class containing an empty main method and have generated an empty shared object emptyhello with the Native Image builder of it:

$ native-image -cp hello EmptyHello
Build on Server(pid: 11228, port: 41223)
[emptyhello:11228]    classlist:     149.59 ms
...

If you do not know what GraalVM distribution is set to the PATH environment To determine if a native image was compiled with GraalVM Community or GraalVM Enterprise, run this command:

$ strings emptyhello | grep com.oracle.svm.core.VM

The expected output should match the following:

com.oracle.svm.core.VM GraalVM  EE

Important: Python source code or LLVM bitcode interpreted or compiled with GraalVM Community will not have the same security characteristics as the same code interpreted or compiled using GraalVM Enterprise. There is a string embedded in each image that allows to figure out the version and variant of the base (Community or Enterprise) used to build an image. The following command will query that information from an image:

strings <path to native-image exe or shared object> | grep com.oracle.svm.core.VM