From 6e80c59d2fa637fd61c94f69a7b084619163e7d6 Mon Sep 17 00:00:00 2001 From: Olya Gupalo Date: Tue, 3 Dec 2024 15:11:30 +0200 Subject: [PATCH] Test and review Native Image guides with JDK 24-EA --- docs/getting-started/oci/cloud-shell.md | 11 +++---- ...tainerise-native-executable-with-docker.md | 20 ++++++------ ...create-heap-dump-from-native-executable.md | 6 ++-- .../include-reachability-metadata-maven.md | 19 ++++++----- .../native-image/guides/include-resources.md | 17 +++++----- .../native-image/guides/optimize-file-size.md | 10 +++--- ...tive-executable-size-using-build-report.md | 4 +-- .../guides/specify-class-initialization.md | 18 +++++------ .../guides/use-system-properties.md | 32 +++++++++++-------- 9 files changed, 71 insertions(+), 66 deletions(-) diff --git a/docs/getting-started/oci/cloud-shell.md b/docs/getting-started/oci/cloud-shell.md index e8eedc0d1980..7bc2e70d0f08 100644 --- a/docs/getting-started/oci/cloud-shell.md +++ b/docs/getting-started/oci/cloud-shell.md @@ -50,18 +50,18 @@ You are all set to run Java applications using Oracle GraalVM JDK in Cloud Shell ## Run a Java Application -The example is a minimal REST-based application, built on top of Spring Boot using Maven. +The example is a minimal REST-based application, built on top of Spring Boot 3 using Maven. The _pom.xml_ file was generated using [Spring Initializr](https://start.spring.io/) with Spring Native Tools added as a feature. The [Spring AOT plugin](https://docs.spring.io/spring-native/docs/current/reference/htmlsingle/#spring-aot) performs ahead-of-time transformations of a Spring application into a native executable. 1. Clone the _demos_ repository and change to the application root directory: ```shell git clone https://github.com/graalvm/graalvm-demos.git - cd graalvm-demos/spring-native-image + cd graalvm-demos/native-image/containerize ``` 2. Build the application with Maven (Apache Maven is also preinstalled in Cloud Shell): ```shell - mvn clean package + ./mvnw clean package ``` This will generate a runnable JAR file that contains all of the application’s dependencies as well as a correctly configured `MANIFEST` file. @@ -85,7 +85,7 @@ The [Spring AOT plugin](https://docs.spring.io/spring-native/docs/current/refere 4. Next, build a native executable for this Spring Boot application using the [`native` Maven profile](https://graalvm.github.io/native-build-tools/latest/maven-plugin.html#quickstart). ```shell - mvn -Pnative native:compile + ./mvnw -Pnative native:compile ``` This will generate a native executable for Linux in the _target_ directory, named _benchmark-jibber_. @@ -115,5 +115,4 @@ Thus, you can use Oracle GraalVM in OCI Cloud Shell to build and test simple Jav - [Java Hello World with Oracle GraalVM in OCI Cloud Shell](https://github.com/graalvm/graalvm-demos/blob/master/java-hello-world-maven/README-Cloud-Shell.md) - [Micronaut Hello World REST App with Oracle GraalVM in OCI Cloud Shell](https://github.com/graalvm/graalvm-demos/blob/master/micronaut-hello-rest-maven/README-Cloud-Shell.md) - [Spring Boot Microservice with Oracle GraalVM in OCI Cloud Shell](https://github.com/graalvm/graalvm-demos/blob/master/spring-native-image/README-Cloud-Shell.md) -- [Oracle GraalVM in OCI Code Editor](code-editor.md) - +- [Oracle GraalVM in OCI Code Editor](code-editor.md) \ No newline at end of file diff --git a/docs/reference-manual/native-image/guides/containerise-native-executable-with-docker.md b/docs/reference-manual/native-image/guides/containerise-native-executable-with-docker.md index ec8d604f707e..5a3681286d84 100644 --- a/docs/reference-manual/native-image/guides/containerise-native-executable-with-docker.md +++ b/docs/reference-manual/native-image/guides/containerise-native-executable-with-docker.md @@ -20,7 +20,7 @@ You will use a GraalVM container image with Native Image to compile a Java appli ## Download a Sample Application -This guide uses the [Spring Boot 3 Native Image Microservice example](https://github.com/graalvm/graalvm-demos/blob/master/spring-native-image/README.md). +This guide uses the [Spring Boot 3 Native Image Microservice example](https://github.com/graalvm/graalvm-demos/tree/master/native-image/containerize/src/main/java/com/example/benchmarks/jibber). The example is a minimal REST-based API application, built on top of Spring Boot 3. If you call the HTTP endpoint `/jibber`, it will return some nonsense verse generated in the style of the Jabberwocky poem, by Lewis Carroll. @@ -33,12 +33,12 @@ For other installation options, visit the [Downloads section](https://www.graalv 2. Clone the GraalVM Demos repository: ```shell - git clone https://github.com/graalvm/graalvm-demos + git clone https://github.com/graalvm/graalvm-demos.git ``` -3. Change directory to _spring-native-image/_: +3. Change directory to _native-image/containerize/_: ```shell - cd spring-native-image + cd graalvm-demos/native-image/containerize ``` ## Build and Run as a Native Executable @@ -71,9 +71,9 @@ With the built-in support for GraalVM Native Image in Spring Boot 3, it has beco The generated native executable is platform-dependent. -1. Containerize the native executable using the following command: +1. Containerize the native executable using the following commands. - - On Linux, containerize the native executable generated in the previous step using the following command: + - On Linux, containerize the native executable generated in the previous step: ```shell docker build -f Dockerfiles/Dockerfile.native --build-arg APP_FILE=benchmark-jibber -t jibber-benchmark:native.0.0.1-SNAPSHOT . ``` @@ -109,10 +109,10 @@ The generated native executable is platform-dependent. In this guide, you saw how to use GraalVM container images to containerize a native executable for your Java application. -With GraalVM Native Image you can build a statically linked native executable by packaging the native executable directly into tiny containers such as scratch or distroless images. +With GraalVM Native Image you can also [build fully static native executables](build-static-and-mostly-static-executable.md) and package them directly into tiny containers such as scratch or distroless containers. ### Related Documentation -* [Build a Static or Mostly-Static Native Executable](build-static-and-mostly-static-executable.md) -* Oracle GraalVM Container Images -* Hands-on Lab: GraalVM Native Image, Spring and Containerisation +* [Build a Native Executable from a Spring Boot Application](build-spring-boot-application-aot.md) +* Oracle GraalVM Container Images +* Hands-on Lab: GraalVM Native Image, Spring and Containerisation \ No newline at end of file diff --git a/docs/reference-manual/native-image/guides/create-heap-dump-from-native-executable.md b/docs/reference-manual/native-image/guides/create-heap-dump-from-native-executable.md index f982d57e87b9..187d84e97cf4 100644 --- a/docs/reference-manual/native-image/guides/create-heap-dump-from-native-executable.md +++ b/docs/reference-manual/native-image/guides/create-heap-dump-from-native-executable.md @@ -25,7 +25,7 @@ All approaches are described below. > Note: By default, a heap dump is created in the current working directory. The `-XX:HeapDumpPath` option can be used to specify an alternative filename or directory. For example: > `./helloworld -XX:HeapDumpPath=$HOME/helloworld.hprof` -> Also note: It is not possible to create a heap dump on the Microsoft Windows platform. +> Creating a heap dump on the Microsoft Windows platform is not supported. ## Create a Heap Dump with VisualVM @@ -168,8 +168,8 @@ For other installation options, visit the [Downloads section](https://www.graalv native-image SVMHeapDump --enable-monitoring=heapdump ``` - (The `native-image` builder creates a native executable from the file _SVMHeapDump.class_. - When the command completes, the native executable _svmheapdump_ is created in the current directory.) + The `native-image` builder creates a native executable from the file _SVMHeapDump.class_. + When the command completes, the native executable _svmheapdump_ is created in the current directory. 3. Run the application, send it a signal, and check the heap dump: diff --git a/docs/reference-manual/native-image/guides/include-reachability-metadata-maven.md b/docs/reference-manual/native-image/guides/include-reachability-metadata-maven.md index 513905c795ff..979a52d7b586 100644 --- a/docs/reference-manual/native-image/guides/include-reachability-metadata-maven.md +++ b/docs/reference-manual/native-image/guides/include-reachability-metadata-maven.md @@ -126,10 +126,12 @@ For other installation options, visit the [Downloads section](https://www.graalv 1.0.0-SNAPSHOT - UTF-8 2.2.220 - h2example + 21 + 21 + 0.10.3 org.graalvm.example.H2Example + h2example @@ -184,10 +186,6 @@ For other installation options, visit the [Downloads section](https://www.graalv org.apache.maven.plugins maven-compiler-plugin 3.11.0 - - ${java.version} - 22 - @@ -327,15 +325,15 @@ In the `native` Maven profile section, add the `exec-maven-plugin` plugin: ``` -3. Run your application with the agent enabled, on the JVM: +3. Run your application with the agent on the JVM: ```shell - mvn -Pnative -Dagent=true -DskipTests -DskipNativeBuild=true package exec:exec@java-agent + mvn -Pnative -DskipTests -DskipNativeBuild=true package exec:exec@java-agent ``` The agent captures and records calls to the H2 Database and all the dynamic features encountered during a test run into the _reachability-metadata.json_ file in the _target/native/agent-output/main/_ directory. 4. Build a native executable using configuration collected by the agent: ```shell - mvn -Pnative -Dagent=true -DskipTests package exec:exec@native + mvn -Pnative -DskipTests package exec:exec@native ``` It generates a native executable for the platform in the _target/_ directory, called _h2example_. @@ -346,7 +344,8 @@ In the `native` Maven profile section, add the `exec-maven-plugin` plugin: ### Summary -This guide demonstrated how to build a native executable using the [GraalVM Reachability Metadata Repository](https://github.com/oracle/graalvm-reachability-metadata) and with the Tracing Agent. The goal was to show the difference, and prove how using the reachability metadata can simplify the work. +This guide demonstrated how to build a native executable using the [GraalVM Reachability Metadata Repository](https://github.com/oracle/graalvm-reachability-metadata) and with the Tracing Agent. +The goal was to show the difference, and prove how using the reachability metadata can simplify the work. Using the GraalVM Reachability Metadata Repository enhances the usability of Native Image for Java applications depending on 3rd party libraries. ### Related Documentation diff --git a/docs/reference-manual/native-image/guides/include-resources.md b/docs/reference-manual/native-image/guides/include-resources.md index 333b15e66c77..bd297b55c216 100644 --- a/docs/reference-manual/native-image/guides/include-resources.md +++ b/docs/reference-manual/native-image/guides/include-resources.md @@ -7,8 +7,8 @@ permalink: /reference-manual/native-image/guides/include-resources/ # 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. +By default, the `native-image` tool does not integrate any resource files into a native executable. +You must specify resources that should be accessible by your application at run time. 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](../ReachabilityMetadata.md#resources) for more ways to include resources. @@ -47,8 +47,8 @@ In the following example, you run a "fortune teller" application that simulates } 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 + 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); @@ -93,11 +93,12 @@ In the following example, you run a "fortune teller" application that simulates 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. +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](https://www.graalvm.org/sdk/javadoc/org/graalvm/nativeimage/hosted/RuntimeResourceAccess.html)). -Learn more about specifying a resource path using a glob and some syntax rules to be observed from [Accessing Resources in Native Image](../ReachabilityMetadata.md#resources). +In this demo the path to the resource file is straightforward, but it may be more complex in real-world use cases. +Resources are specified via globs. +For more advanced use-cases, you can register resources using the API methods (see [class RuntimeResourceAccess](https://www.graalvm.org/sdk/javadoc/org/graalvm/nativeimage/hosted/RuntimeResourceAccess.html)). +Learn more about specifying a resource path using a glob and some syntax rules to be observed in [Accessing Resources in Native Image](../ReachabilityMetadata.md#resources). ### Related Documentation diff --git a/docs/reference-manual/native-image/guides/optimize-file-size.md b/docs/reference-manual/native-image/guides/optimize-file-size.md index f7bc387d1456..1c05fc0892ec 100644 --- a/docs/reference-manual/native-image/guides/optimize-file-size.md +++ b/docs/reference-manual/native-image/guides/optimize-file-size.md @@ -27,14 +27,14 @@ For the demo, run a "fortune teller" application that simulates the traditional 2. Change directory to _fortune-demo/fortune-maven_: ```bash - cd fortune-demo/fortune-maven + cd native-image/native-build-tools/maven-plugin ``` ## Build a Native Executable with Default Configuration -1. Create a native executable using the [Maven plugin for Native Image](https://graalvm.github.io/native-build-tools/latest/maven-plugin.html){:target="_blank"}: +1. Create a native executable using the [Maven plugin for Native Image building](https://graalvm.github.io/native-build-tools/latest/maven-plugin.html){:target="_blank"}: ```bash - mvn -Pnative package + ./mvnw -Pnative package ``` The command compiles the project, creates a JAR file with all dependencies, and then generates a native executable, `fortune`, in the _target_ directory. @@ -53,7 +53,7 @@ For the demo, run a "fortune teller" application that simulates the traditional Next create a native executable with the size optimization on, giving a different name for the output file to differentiate it from the previous build. -1. Open the _pom.xml_ file. Find the `native-maven-plugin` declaration, and add the following build arguments within the `` element. The configuration should look like this: +1. Open the _pom.xml_ file. Find the `native-maven-plugin` declaration, and notice the following build arguments within the `` element: ```xml fortune-optimized @@ -68,7 +68,7 @@ Next create a native executable with the size optimization on, giving a differen 2. Create the second native executable: ```bash - mvn -Pnative package + ./mvnw -Pnative package ``` The command generates an executable file, `fortune-optimized`, in the _target_ directory. diff --git a/docs/reference-manual/native-image/guides/optimize-native-executable-size-using-build-report.md b/docs/reference-manual/native-image/guides/optimize-native-executable-size-using-build-report.md index fdef568c59ca..d2a99b4d3db2 100644 --- a/docs/reference-manual/native-image/guides/optimize-native-executable-size-using-build-report.md +++ b/docs/reference-manual/native-image/guides/optimize-native-executable-size-using-build-report.md @@ -65,10 +65,10 @@ The words are delimited by commas and may be enclosed by an arbitrary number of native-image IthWord --emit build-report ``` - The command generates an executable file, `_ithword_`, in the current working directory. + The command generates an executable file, `ithword`, in the current working directory. The Build Report file, _ithword-build-report.html_, is automatically created alongside the native executable. A link to the report is also listed in the _Build artifacts_ section at the end of the build output. - You can specify a different filename or path for the report by appending it to the `build-report` argument, for example, `--emit build-report=/tmp/custom-name-build-report.html`. + You can specify a different filename or path for the report by appending it to the `build-report` option, for example, `--emit build-report=/tmp/custom-name-build-report.html`. (Optional) Run this executable with the same argument: ```shell diff --git a/docs/reference-manual/native-image/guides/specify-class-initialization.md b/docs/reference-manual/native-image/guides/specify-class-initialization.md index 4d8e67f91582..2dba798c61c1 100644 --- a/docs/reference-manual/native-image/guides/specify-class-initialization.md +++ b/docs/reference-manual/native-image/guides/specify-class-initialization.md @@ -7,22 +7,22 @@ permalink: /reference-manual/native-image/guides/specify-class-initialization/ # Specify Class Initialization Explicitly -By default, Native Image initializes application classes at runtime, except for the classes that Native Image proves "safe" for initialization at build time. -However, you can influence the default behavior by explicitly specifying the classes to be initialized at build-time or runtime. +By default, Native Image initializes application classes at run time, except for the classes that Native Image proves "safe" for initialization at build time. +However, you can influence the default behavior by explicitly specifying the classes to be initialized at build-time or run time. For that, there are two command-line options: `--initialize-at-build-time` and `--initialize-at-run-time`. You can use these options to specify whole packages or individual classes. For example, if you have the classes `p.C1`, `p.C2`, … ,`p.Cn`, you can specify that all the classes in the package `p` are to be initialized at build time by passing the following option to `native-image`: ```shell --initialize-at-build-time=p ``` -If you want only class `C1` in package `p` to be initialized at runtime, use: +If you want only class `C1` in package `p` to be initialized at run time, use: ```shell --initialize-at-run-time=p.C1 ``` You can also programmatically specify class initialization using the [`RuntimeClassInitialization`] class (https://github.com/oracle/graal/blob/master/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/RuntimeClassInitialization.java) from the [Native Image Feature interface](https://github.com/oracle/graal/blob/master/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/Feature.java). -This guide demonstrates how to build a native executable by running the class initializer at runtime (default behavior), and then at build time, and compares the two approaches. +This guide demonstrates how to build a native executable by running the class initializer at run time (default behavior), and then at build time, and compares the two approaches. ### Prerequisite Make sure you have installed a GraalVM JDK. @@ -71,7 +71,7 @@ The parser creates records and adds them to a `List` collection. javac TalkParser.java ``` -3. Build a native executable, explicitly running the class initializer at runtime: +3. Build a native executable, explicitly running the class initializer at run time: ```bash native-image --initialize-at-run-time=TalkParser,Talk -o runtime-parser TalkParser ``` @@ -91,14 +91,14 @@ The parser creates records and adds them to a `List` collection. - Bootiful Spring Boot 3 by Josh Long ./runtime-parser 0.00s user 0.00s system 52% cpu 0.010 total ``` - The application parses the text block at runtime. + The application parses the text block at run time. Check the file size which should be around 13M: ``` du -sh runtime-parser ``` -5. Next, build a native executable initializing `TalkParser` at build time, and providing a different name for the output file to differentiate it from the previous build. The `Talk` record has to be initialized explicitly too, so the objects of this type will be persisted in the executable heap. +5. Next, build a native executable initializing `TalkParser` at build time, and providing a different name for the output file to differentiate it from the previous build. The `Talk` record has to be initialized explicitly too, so the objects of this type will be persisted in the image heap. ```bash native-image --initialize-at-build-time=TalkParser,Talk -o buildtime-parser TalkParser ``` @@ -165,11 +165,11 @@ Talks loaded using scanner: 0.002226000 seconds sys ``` -This demonstrates how Native Image can shift work from runtime to build time: when the class is initialized at build time, the text block is parsed when the executable is being built and only the parsed objects are included. +This demonstrates how Native Image can shift work from run time to build time: when the class is initialized at build time, the text block is parsed when the executable is being built and only the parsed objects are included. This not only makes the executable smaller in file size, but also faster to run: when the executable runs, the `Talk` records already exist and only need to be printed.
-To ensure native executables built with Native Image are as compatible as possible with the HotSpot behavior, application classes that cannot be safely initialized at build time, are initialized at runtime. +To ensure native executables built with Native Image are as compatible as possible with the HotSpot behavior, application classes that cannot be safely initialized at build time, are initialized at run time. You as a user, or a framework that you use, must explicitly request build-time initialization for certain classes to benefit from smaller file sizes and faster times to run. Include the right data structures to avoid the image size blowing up instead. We also recommend using `--initialize-at-build-time` with single classes only. diff --git a/docs/reference-manual/native-image/guides/use-system-properties.md b/docs/reference-manual/native-image/guides/use-system-properties.md index 91a6fb33dd7e..78acfb6e7db8 100644 --- a/docs/reference-manual/native-image/guides/use-system-properties.md +++ b/docs/reference-manual/native-image/guides/use-system-properties.md @@ -21,11 +21,11 @@ If you build a native executable using `native-image -Dfoo=bar App`, the system This means it is available to the [code in your application that is run at build time](http://www.graalvm.org/sdk/javadoc/org/graalvm/nativeimage/ImageInfo.html#inImageBuildtimeCode--) (usually static field initializations and static initializers). Thus, if you run the resulting executable, it will not contain `foo` in the printed list of properties. -If, on the other hand, you run the executable with `app -Dfoo=bar`, it will display `foo` in the list of properties because you specified property at *executable runtime*. +If, on the other hand, you run the executable with `app -Dfoo=bar`, it will display `foo` in the list of properties because you specified property at *executable run time*. In other words: -* Pass `-D=` as an argument to `native-image` to control the properties seen at build time. -* Pass `-D=` as an argument to a native executable to control the properties seen at runtime. +* Pass `-D=` as an option to `native-image` to control the properties seen at build time. +* Pass `-D=` as an option to a native executable to control the properties seen at run time. ## Read System Properties at Build Time @@ -36,7 +36,7 @@ Make sure you have installed a GraalVM JDK. The easiest way to get started is with [SDKMAN!](https://sdkman.io/jdks#graal). For other installation options, visit the [Downloads section](https://www.graalvm.org/downloads/). -1. Save the following Java code into a file named _ReadProperties.java_, then compile it using `javac`: +1. Save the following Java code into a file named _ReadProperties.java_: ```java public class ReadProperties { private static final String STATIC_PROPERTY_KEY = "static_key"; @@ -65,7 +65,12 @@ For other installation options, visit the [Downloads section](https://www.graalv } ``` -2. Build the native executable, passing a system property as a command-line argument. Then run the native executable, passing a different system property on the command line. +2. Compile the application: + ```shell + javac ReadProperties.java + ``` + +3. Build the native executable, passing a system property as a command-line option. Then run the native executable, passing a different system property on the command line. ```shell native-image -Dstatic_key=STATIC_VALUE ReadProperties ``` @@ -81,26 +86,27 @@ For other installation options, visit the [Downloads section](https://www.graalv Value of instance property: INSTANCE_VALUE ``` - This indicates that the class static initializer was not run at build time, but at **runtime**. + This indicates that the class static initializer was not run at build time, but at **run time**. -3. To force the class static initializer to run at build time, use the `--initialize-at-build-time` flag, as follows: +4. To force the class static initializer to run at build time, use the `--initialize-at-build-time` option, as follows: ```shell native-image --initialize-at-build-time=ReadProperties -Dstatic_key=STATIC_VALUE ReadProperties ``` - In the output from the `native-image` tool you should see output similar to the following: - ```shell - ... - [1/7] Initializing... (7.7s @ 0.07GB) + In the output from the `native-image` tool you should see the message like this: + ``` + GraalVM Native Image: Generating 'readproperties' (executable)... + ========================================================================== Getting value of static property with key: static_key + [1/8] Initializing... (4.0s @ 0.13GB) ... ``` - 4. Run the executable again, as follows: +5. Run the executable again, as follows: ```shell ./readproperties -Dinstance_key=INSTANCE_VALUE ``` - This time you should see the following output, confirming that the static initializer was run at **build time**, not at runtime. + This time you should see the following output, confirming that the static initializer was run at **build time**, not at run time. ```shell Value of static property: STATIC_VALUE