Back

Troubleshoot Native Image Run-Time Errors

A successful ahead-of-time compilation can still generate images that crash at run time or do not behave the same way as the application would behave on a Java VM. In this guide, some reasons for that are shown, along with the strategies to diagnose and resolve the issues.

Note that sometimes upgrading to the latest version of GraalVM can already resolve an issue.

1. Diagnose Missing Metadata Registration

Start by diagnosing if there is any metadata configuration missing. Native Image requires all utilized classes to be known during the build. The static analysis tries to make predictions about the run-time behavior of your application. In some cases, you need to provide the analysis with configuration to make all dynamic feature calls visible to it. Failing to do so will result in an image that terminates at run-time with hard-to-diagnose errors once the dynamic feature is used in the application. This can be avoided by eagerly checking for missing metadata.

  1. Pass the --exact-reachablity-metadata option to the native-image tool and rebuild the application. If you want to do this only for a specific package, specify a package prefix --exact-reachablity-metadata=[package prefix].

    This option was introduced in GraalVM for JDK 23 and will become the default in the next feature release. It is equivalent to the -H:ThrowMissingRegistrationErrors= host option.

  2. Next run that native executable passing the -XX:MissingRegistrationReportingMode=Warn option to find all places in your code where missing registrations occur.

  3. If there is some missing metadata reported, make sure to add it to the reachability-metadata.json file. See how to do it in the Reachability Metadata documentation.

  4. Then restart the native executable with -XX:MissingRegistrationReportingMode=Exit to detect places where the application accidentally ignores a missing registration error (with catch (Throwable t) blocks). The application will then unconditionally print the error message with the stack trace and exit immediately. This behavior is ideal for running application tests to guarantee all metadata is included.

Shared Libraries

For diagnosing shared libraries built with Native Image, you can either:

  • specify -R:MissingRegistrationReportingMode=Exit when building a native shared library;
  • or specify -XX:MissingRegistrationReportingMode=Exit when the isolate is created. graal_create_isolate_params_t has argc (_reserved_1) and argv (_reserved_2) fields that can be used to pass C-style command-line options at run time. However, note that both fields are currently not public APIs.

2. Set java.home Explicitly

If your application code uses the java.home property, set it explicitly with -Djava.home=<path> when running a native executable. Otherwise, the System.getProperty("java.home") call will return a null value.

3. Enable URL Protocols

Try enabling all URL protocols on-demand at build time: --enable-url-protocols=<protocols>. To enable the HTTPS support only, pass --enable-https.

4. Enable Signal Handling

If your application is using signal handling or the java.lang.Terminator exit handlers, provide the option --install-exit-handlers option at build time.

5. Include All Charsets and Locales

Other handy options are -H:+AddAllCharsets to add charsets support, and -H:+IncludeAllLocales to pre-initialize support for locale-sensitive behavior in the java.util and java.text packages. Pass those options at build time. This might increase the size of the resulting binary.

6. Add Missing Security Providers

If your application is using Security Providers, try to pre-initialize security providers by passing the option -H:AdditionalSecurityProviders=<list-of-providers> at build time. Here is a list of all JDK security providers to choose from: sun.security.provider.Sun,sun.security.rsa.SunRsaSign,sun.security.ec.SunEC,sun.security.ssl.SunJSSE,com.sun.crypto.provider.SunJCE,sun.security.jgss.SunProvider,com.sun.security.sasl.Provider,org.jcp.xml.dsig.internal.dom.XMLDSigRI,sun.security.smartcardio.SunPCSC,sun.security.provider.certpath.ldap.JdkLDAP,com.sun.security.sasl.gsskerb.JdkSASL.

7. File a Native Image Run-Time Issue

Only if you tried all the above suggestions, file a Native Image Run-Time Issue Report at GitHub, filling out the necessary information.

To gather the required information for filing a proper and actionable ticket, it is recommended to run a native-image build with the diagnostics mode enabled. Pass the --diagnostics-mode option enabling diagnostics output for class initialization, substitutions, and so on.

Connect with us