Back

Include Resources in a Native Executable

By default, the native-image tool does not integrate any Java resource files into a native executable. You must specify resources that should be accessible by your application at runtime.

This guide demonstrates how to register resources to be included in a native executable by providing a resource configuration file. See Accessing Resources in Native Image for more ways to include resources.

Prerequisite

Make sure you have installed a GraalVM JDK. The easiest way to get started is with SDKMAN!. For other installation options, visit the Downloads section.

Run a Demo

In the following example, you run a “fortune teller” application that simulates the traditional fortune Unix program (for more information, see fortune).

  1. Save the following Java source code as a file named Fortune.java:
     import java.io.BufferedReader;
     import java.io.InputStreamReader;
     import java.util.ArrayList;
     import java.util.Random;
     import java.util.Scanner;
    
     public class Fortune {
    
         private static final String SEPARATOR = "%";
         private static final Random RANDOM = new Random();
         private ArrayList<String> fortunes = new ArrayList<>();
    
         public Fortune(String path) {
             // Scan the file into the array of fortunes
             Scanner s = new Scanner(new BufferedReader(new InputStreamReader(this.getClass().getResourceAsStream(path))));
             s.useDelimiter(SEPARATOR);
             while (s.hasNext()) {
                 fortunes.add(s.next());
             }
         }
            
         private void printRandomFortune() throws InterruptedException {
             int r = RANDOM.nextInt(fortunes.size()); //Pick a random number
             String f = fortunes.get(r);  //Use the random number to pick a random fortune
             for (char c: f.toCharArray()) {  // Print out the fortune
               System.out.print(c);
                 Thread.sleep(100); 
             }
         }
          
         public static void main(String[] args) throws InterruptedException {
             Fortune fortune = new Fortune("/fortunes.u8");
             fortune.printRandomFortune();
         }
     }
    
  2. Download the fortunes.u8 resource file and save it in the same directory as Fortune.java.

  3. Create a configuration file, named resource-config.json, and save it in the META-INF/native-image/ subdirectory. Register the resource using a glob pattern:
     {
     "globs": [
         {
         "glob": "fortunes.u8"
         }
       ]
     }
    

    The native-image tool picks up all configuration files that it finds in the META-INF/native-image/ directory automatically.

  4. Compile the application:
     javac Fortune.java
    
  5. Build a native executable:
     native-image Fortune
    
  6. Run the fortune teller application to test:
     ./fortune
    

To see which resources were included in your native executable, pass the option --emit build-report to the native-image tool at build time. It generates an HTML file that can be examined with a regular web browser. The information about all included resources will be under the Resources tab.

In this demo the path to the resource file is straightforward, but it may be more complex in a real-world use case. Resources are specified via globs. For more advanced use-cases, you can register resources using the API methods (see class RuntimeResourceAccess). Learn more about specifying a resource path using a glob and some syntax rules to be observed from Accessing Resources in Native Image.

Connect with us