diff --git a/docs/src/docs/asciidoc/css/page.css b/docs/src/docs/asciidoc/css/page.css index 0a41ded6..a5b295f8 100644 --- a/docs/src/docs/asciidoc/css/page.css +++ b/docs/src/docs/asciidoc/css/page.css @@ -98,10 +98,6 @@ ul.sectlevel2 a { font-weight: 200 !important; } -ul.sectlevel2 a:hover { - font-weight: 400 !important; -} - #toc a:hover { color: #8EC9E6; } diff --git a/docs/src/docs/asciidoc/gradle-plugin.adoc b/docs/src/docs/asciidoc/gradle-plugin.adoc index de3c0093..abb3e43a 100644 --- a/docs/src/docs/asciidoc/gradle-plugin.adoc +++ b/docs/src/docs/asciidoc/gradle-plugin.adoc @@ -4,9 +4,6 @@ The GraalVM team image:https://github.com/graalvm/native-build-tools/actions/workflows/test-native-gradle-plugin.yml/badge.svg[] -[[introduction]] -== Introduction - The {doctitle} adds support for building and testing native images using the https://gradle.org[Gradle build tool]. Find the differences between the versions in the <>. @@ -14,37 +11,29 @@ Find the differences between the versions in the <> which provides step-by-step directions on adding the Gradle plugin to your project, building your first native image, and running it. + +[NOTE] +==== +The plugin requires that you install a https://www.graalvm.org/downloads/[GraalVM JDK]. +==== -Add following to `plugins` section of the project's _build.gradle_ / _build.gradle.kts_ file: +The plugin is enabled by adding its declaration to the _build.gradle_ / _build.gradle.kts_ file within the `plugins` block: [source,groovy,subs="verbatim,attributes", role="multi-language-sample"] ---- -plugins { - // ... - - // Apply GraalVM Native Image plugin id 'org.graalvm.buildtools.native' version '{gradle-plugin-version}' -} ---- [source,kotlin,subs="verbatim,attributes",role="multi-language-sample"] ---- -plugins { - // ... - - // Apply GraalVM Native Image plugin id("org.graalvm.buildtools.native") version "{gradle-plugin-version}" -} ---- -[NOTE] -==== This plugin supplements and heavily relies on regular Java plugins such as `application`, `java-library`, `java`, and others. Not having them included in your project will most probably cause errors. -==== -[TIP] -==== You can use development versions of the plugin by adding the snapshot repository instead. Pre-releases are provided for convenience, without any guarantee. [source, groovy, role="multi-language-sample"] ---- @@ -55,35 +44,22 @@ include::../snippets/gradle/groovy/settings.gradle[tags=pre-release, indent=0] ---- include::../snippets/gradle/kotlin/settings.gradle.kts[tags=pre-release, indent=0] ---- -==== - -[[installing-graalvm]] -== Installing GraalVM -The plugin requires that you https://www.graalvm.org/latest/docs/getting-started/[install GraalVM]. -The easiest way to install GraalVM is to use the https://sdkman.io/jdks[SDKMAN!]. -For other installation options, go to https://www.graalvm.org/downloads/[GraalVM Downloads]. - -By default, the plugin attempts to use the `native-image` tool bundled with the JDK running Gradle. -Therefore, you must ensure that Gradle runs on a GraalVM JDK. - -You may choose to: +[[configuration-toolchains]] +== Using Gradle Toolchains -1. Set the `GRAALVM_HOME` environment variable to point to your GraalVM installation. When this variable is configured, the JDK specified at this location will be used for Native Image builds. -2. <>. +Check out https://docs.gradle.org/current/userguide/compatibility.html[which Java versions are compatible with the Gradle version] you are using. [TIP] ==== -Check out https://docs.gradle.org/current/userguide/compatibility.html[which Java versions are compatible with the Gradle version] you are using. -In case the Gradle version you are using is not compatible with the GraalVM version, +If the Gradle version you are using is not compatible with the GraalVM version, you can set up the `GRAALVM_HOME` environment variable pointing to your GraalVM installation, and the `JAVA_HOME` environment variable pointing to some JDK that is compatible with the Gradle on your system. ==== -[[configuration-toolchains]] -=== Using Gradle toolchains - [[configuration-toolchains-enabling]] -==== Enabling toolchain detection +=== Enabling Toolchain Detection + +WARNING: Toolchain support has many pitfalls. Unless you have a single JDK installed on your machine, which is the GraalVM version that you want to use, we do not recommend enabling them yet. We are working with the Gradle team on improvements in the future. Instead of relying on the JDK which is used to run Gradle, you can use the https://docs.gradle.org/current/userguide/toolchains.html[Gradle toolchain support] to select a specific GraalVM installation. @@ -103,7 +79,7 @@ include::../snippets/gradle/groovy/build.gradle[tags=enabling-toolchain, indent= include::../snippets/gradle/kotlin/build.gradle.kts[tags=enabling-toolchain, indent=0] ---- -==== Selecting the GraalVM toolchain +=== Selecting the GraalVM Toolchain By default, the plugin will select a Java 11 GraalVM toolchain using the vendor string `GraalVM`, which works properly for GraalVM up to version 22.3 included. More recent versions of GraalVM do not have a specific version and are aligned with the language version they support. @@ -124,12 +100,12 @@ Again, be aware that the toolchain detection _cannot_ distinguish between GraalV If you have both installed on the machine, Gradle may randomly pick one or the other. [[configuration]] -== Plugin configuration +== Plugin Configuration The plugin works with the `application` plugin and registers a number of tasks and extensions for you to configure. [[available-tasks]] -=== Available tasks +=== Available Tasks The main tasks that you may want to execute are: @@ -143,7 +119,7 @@ Those tasks are configured with reasonable defaults using the `graalvmNative` ex The main executable is configured by the image named `main`, while the test executable is configured via the image named `test`. [[configure-native-image]] -=== Native Image configuration +=== Native Image Configuration The link:javadocs/native-gradle-plugin/org/graalvm/buildtools/gradle/dsl/NativeImageOptions.html[NativeImageOptions] allows you to tweak how the native image is going to be built. The plugin allows configuring the final binary, the <> one, as well as apply options to both. @@ -176,7 +152,7 @@ include::../snippets/gradle/kotlin/build.gradle.kts[tags=all-config-options] ---- [[native-image-options]] -==== Native Image options +=== Native Image options - `imageName` - The name of the native executable, defaults to the project name - `mainClass` - The main class to use, defaults to the _application.mainClass_ @@ -203,7 +179,7 @@ For options that can be set using the command line, if both DSL and command-line ==== [[native-image-tracing-agent]] -==== Native Image Tracing Agent +== Native Image Tracing Agent If your project requires reflection, classpath resources, dynamic proxies, or other features that need explicit configuration, it may be helpful to first run your application or tests using the https://www.graalvm.org/reference-manual/native-image/metadata/AutomaticMetadataCollection/[Native Image Tracing Agent]. @@ -294,7 +270,23 @@ If you want to **enable the agent on the command line**, you can specify in whic ./gradlew -Pagent=direct nativeTest ---- -==== MetadataCopy task +[[resources-autodetecting]] +=== Resources Autodetecting + +You can instruct the plugin to automatically detect resources to be included in a native executable at build time: +Add this to your _build.gradle_ file: + +[source,groovy,subs="verbatim,attributes", role="multi-language-sample"] +---- +graalvmNative { + binaries.all { + resources.autodetect() + } +} +---- + +[[metadatacopy-task]] +=== MetadataCopy Task Once the metadata is collected, it can be copied into the project using the `metadataCopy` task. To do so, add the following block inside your `agent` block: @@ -331,7 +323,10 @@ Inside this block, you configure: Then you can copy metadata to the location you specified with: - +[source,bash,subs="verbatim,attributes", role="multi-language-sample"] +---- +./gradlew metadataCopy +---- [TIP] ==== @@ -346,7 +341,7 @@ You can configure the `metadataCopy` task on the command line as well: ==== [[common-agent-options]] -==== Common agent options +=== Common Agent Options All the mentioned modes share certain common configuration options like: @@ -432,7 +427,7 @@ agent { ---- [[agent-filter-file]] -==== Reduce the amount of generated metadata +=== Reduce the Amount of Generated Metadata In some cases the agent may include more metadata than it is actually needed. You can filter metadata using the agent filter files. @@ -607,7 +602,7 @@ After updating the filter, you can regenerate the metadata, which will result in As you can see there are no more entries that contain classes from `org.junit` (as their condition). [[max_parallel_builds]] -==== Max parallel builds +=== Max Parallel Builds When using Gradle parallel builds, the plugin automatically limits the number of native images which can be built concurrently, in order to limit CPU and memory usage. By default, it is limited to the number of CPU cores / 16, but you can change this limit either by setting the `org.graalvm.buildtools.max.parallel.builds` gradle property (in your _gradle.properties_ file), or by setting the `GRAALVM_BUILDTOOLS_MAX_PARALLEL_BUILDS` environment variable. @@ -615,12 +610,11 @@ By default, it is limited to the number of CPU cores / 16, but you can change th [[configuration-advanced]] [[long_classpath_and_fat_jar_support]] -==== Long classpath, @argument file, and fat JAR support +=== Long classpath, @argument File, and a Fat JAR Support The plugin automatically passes arguments to the `native-image` tool from the argument file, which should prevent all https://github.com/graalvm/native-build-tools/issues/85[long classpath issues] under Windows. However, if you are using an older GraalVM release (older than 21.3) which doesn't support argument files, you will need to rely on creating a "fat JAR", which includes all entries from the classpath automatically, to workaround the problem: -.Enabling the fat JAR creation [source, groovy, role="multi-language-sample"] ---- include::../snippets/gradle/groovy/build.gradle[tags=enable-fatjar] @@ -646,7 +640,7 @@ include::../snippets/gradle/kotlin/build.gradle.kts[tags=custom-fatjar] When the `classpathJar` property is set, the `classpath` property is _ignored_. [[testing-support]] -== Testing support +== Testing Support The plugin supports running tests on the https://junit.org/junit5/docs/current/user-guide/[JUnit Platform] as native images. @@ -669,7 +663,7 @@ To execute the tests, run: ---- [[test-binary-config]] -=== Configuring test image options +=== Configuring Test Image Options You can fine-tune the test binary using the `test` binary configuration. The following example prints additional data for troubleshooting and sets the minimal optimizations. @@ -685,7 +679,7 @@ include::../snippets/gradle/kotlin/build.gradle.kts[tags=configure-test-binary] ---- [[testing-support-disabling]] -=== Disabling testing support +=== Disabling Testing Support There are cases where you might want to disable running native tests: @@ -695,7 +689,6 @@ There are cases where you might want to disable running native tests: In this case, you can disable native testing support by configuring the `graalvmNative` option as follows: -.Disabling testing support [source,groovy,role="multi-language-sample"] ---- include::../snippets/gradle/groovy/build.gradle[tags=disable-test-support] @@ -707,7 +700,7 @@ include::../snippets/gradle/kotlin/build.gradle.kts[tags=disable-test-support] ---- [[extra-test-suites]] -=== Configuring additional test suites +=== Configuring Additional Test Suites It is common to have multiple test source sets in a Gradle build. Typically, you may have an integration test suite, or a functional test suite, in addition to the unit test suite. @@ -734,7 +727,7 @@ The plugin then automatically creates the following tasks: The same mechanism can be used if you have multiple test tasks for a single test source set, which is often the case with manual test sharding. [[metadata-support]] -== GraalVM Reachability Metadata support +== GraalVM Reachability Metadata Support The plugin adds support for the https://github.com/oracle/graalvm-reachability-metadata/[GraalVM Reachability Metadata Repository]. This repository provides the https://www.graalvm.org/latest/reference-manual/native-image/metadata/[configuration] for libraries that do not support GraalVM Native Image. @@ -744,7 +737,7 @@ This repository provides the https://www.graalvm.org/latest/reference-manual/nat The GraalVM Reachability Metadata Repository is also published on Maven Central at the following coordinates: `org.graalvm.buildtools:graalvm-reachability-metadata:graalvm-reachability-metadata` with the `repository` classifier and `zip` extension, for example, `graalvm-reachability-metadata-{gradle-plugin-version}-repository.zip`. ==== -=== Configuring the metadata repository +=== Configuring the Metadata Repository The plugin automatically downloads the configuration metadata from the official repository if you supply the version of the repository you want to use. @@ -811,7 +804,7 @@ include::../snippets/gradle/groovy/build.gradle[tags=specify-metadata-version-fo include::../snippets/gradle/kotlin/build.gradle.kts[tags=specify-metadata-version-for-library] ---- -=== Including metadata repository files +=== Including Metadata Repository Files By default, reachability metadata is used only when your native image is being generated. In some situations, you may want a copy of the reachability metadata to use it directly. @@ -839,13 +832,18 @@ For more advanced configurations you can declare the `org.graalvm.buildtools.gra [[pgo-support]] == Profile-Guided Optimization -The plugin supports building images with https://www.graalvm.org/latest/reference-manual/native-image/guides/optimize-native-executable-with-pgo/[Profile-Guided Optimization (PGO)]. +The plugin supports building optimized images with https://www.graalvm.org/latest/reference-manual/native-image/optimizations-and-performance/PGO/[Profile-Guided Optimization (PGO)] to improve performance and throughput. -It works in 3 phases: +[NOTE] +==== +PGO is available in Oracle GraalVM. +==== -- the first one consists in generating a native image with instrumentation enabled -- the second phase consists in running the image in order to gather profiling information -- the third phase consists in creating an optimized native image based on the profiles +The PGO workflow includes three steps: + +- First, generate a native image with instrumentation enabled. +- Next, run the image to gather profiling information. +- Then, create an optimized native image based on the profiles. To generate a binary with instrumentation enabled, you should run the `nativeCompile` command with the `--pgo-instrument` command line option: @@ -859,7 +857,7 @@ You can run this image to gather profiling data: [source,bash, role="multi-language-sample"] ---- -./my-app-instrumented +./myApp-instrumented ---- A _default.iprof_ file will be generated once the application is stopped. @@ -883,10 +881,13 @@ Copy _default.iprof_ into that directory, and then run: ---- The profile will automatically be used. +If everything was done properly, you will see _"PGO: user-provided"_ in the native image build output. + It is possible to include more than one profile, in which case you should rename the _.iprof_ files in the _src/pgo-profiles/main_ directory. +Learn more about PGO https://www.graalvm.org/reference-manual/native-image/optimizations-and-performance/PGO/basic-usage[on the website]. [[plugin-configurations]] -== Configurations defined by the plugin +== Configurations Defined by the Plugin For each binary (`main` and `test`), the plugin declares 2 configurations that users or plugin authors can use to tweak the native image compilation classpath: @@ -910,4 +911,4 @@ include::../../../../samples/java-application-with-extra-sourceset/build.gradle. == Javadocs -For further reference, you can review the link:javadocs/native-gradle-plugin/index.html[Javadocs of the plugin]. \ No newline at end of file +For further reference, you can review the link:javadocs/native-gradle-plugin/index.html[Javadocs of the plugin]. diff --git a/docs/src/docs/asciidoc/maven-plugin.adoc b/docs/src/docs/asciidoc/maven-plugin.adoc index 1cad90db..2fb56fdd 100644 --- a/docs/src/docs/asciidoc/maven-plugin.adoc +++ b/docs/src/docs/asciidoc/maven-plugin.adoc @@ -4,9 +4,6 @@ The GraalVM team image:https://github.com/graalvm/native-build-tools/actions/workflows/test-native-maven-plugin.yml/badge.svg[] -[[introduction]] -== Introduction - The {doctitle} adds support for building and testing native images using https://maven.apache.org[Apache Maven]™. Find the differences between the versions in the <>. @@ -14,91 +11,20 @@ Find the differences between the versions in the < - - native - - - - org.graalvm.buildtools - native-maven-plugin - ${native.maven.plugin.version} - true - - - build-native - - compile-no-fork - - package - - - test-native - - test - - test - - - - - - - - - - -``` - -You can then build a native image directly with Maven: - -[source,bash,subs="verbatim,attributes"] ----- -./mvnw -Pnative package ----- - -The `native-maven-plugin` plugin figures out which JAR file it needs to pass to `native-image`, and what the executable main class should be. -If the heuristics fail with the `no main manifest attribute, in target/.jar` error, the main class should be -specified in the `` block of the plugin. -A native image is generated in the _target_ directory of the project. +Refer to the <> which provides step-by-step directions on adding the Gradle plugin to your project, building your first native image, and running it. [NOTE] ==== -Building a native executable without attaching to the `package` phase can be done by invoking the `compile` goal directly. For example: `./mvnw native:compile`. -==== - -[TIP] -==== -You can use development versions of the plugin by adding the snapshot repository. Pre-releases are provided for convenience, without any guarantee. -[source,xml, role="multi-language-sample"] ----- - - - graalvm-native-build-tools-snapshots - GraalVM native-build-tools Snapshots - https://raw.githubusercontent.com/graalvm/native-build-tools/snapshots - - false - - - true - - - ----- +The plugin requires that you install a https://www.graalvm.org/downloads/[GraalVM JDK]. ==== [[configuration-options]] -== Plugin configuration +== Plugin Configuration [[native-image-options]] -=== Native Image options +=== Native Image Options The plugin picks up all the configuration for your application stored below the _META-INF/native-image/_ resource location, as described in https://www.graalvm.org/reference-manual/native-image/BuildConfiguration/[Native Image Build Configuration]. @@ -243,7 +169,7 @@ Most of the aforementioned properties can also be set on the command line as a p ==== [[native-image-tracing-agent]] -=== Native Image Tracing Agent +== Native Image Tracing Agent If your project requires reflection, classpath resources, dynamic proxies or other features requiring explicit native configuration, it may prove helpful to first run your @@ -256,7 +182,7 @@ The agent generates the configuration file(s) under _target/native/agent-output_ Although those files will be automatically used by `native-image`, you should consider reviewing the generated files and adding them to your sources instead. [[agent-support-enabling]] -==== Enabling the agent +=== Enabling the Agent The agent is disabled by default, but it can be enabled in the _pom.xml_ file or on the command line. @@ -280,7 +206,7 @@ If you have enabled the agent in _pom.xml_, you can still disable it on the comm ==== [[agent-support-configuring-options]] -==== Configuring agent options +=== Configuring the Agent If you would like to configure the options for the agent -- for example, to configure agent mode or advanced features such as https://www.graalvm.org/latest/reference-manual/native-image/metadata/AutomaticMetadataCollection/#caller-based-filters[Caller-based Filters] @@ -311,7 +237,7 @@ Here is an explanation for each option you can specify in the agent block: * `options` - A list of options that can be specified independently from the agent mode. Learn more about these options https://www.graalvm.org/latest/reference-manual/native-image/metadata/AutomaticMetadataCollection/[here]. [[agent-support-running-tests]] -==== Running tests with the agent +=== Running Tests with the Agent The simplest way to use the agent is to do it via execution of your tests. @@ -336,7 +262,7 @@ at the end of the agent invocation command. For example: ==== [[agent-support-running-application]] -==== Running your application with the agent +=== Running the Application with the Agent Executing your application with the agent is more involved and requires you to configure a separate Mojo execution which allows forking the Java process. @@ -361,7 +287,7 @@ If you want to run your native application with those configuration files, you t ---- [[agent-filter-file]] -==== Reduce the amount of generated metadata +=== Reducing the Amount of Generated Metadata In some cases the agent may include more metadata than it is actually needed. You can filter metadata using the agent filter file(s). @@ -559,7 +485,6 @@ As you can see, there are lots of entries that you likely do not want. They are present because the metadata was generated using tests, and that the testing library was present at run time during the agent execution pass, but in practice, your application will not use the testing library in production. To reduce the amount of generated metadata, use the following _user-code-filter.json_: - [source,json,subs="verbatim,attributes", role="multi-language-sample"] ---- { @@ -609,7 +534,7 @@ After updating the filter, you can regenerate the metadata, which will result in As you can see, there are no more entries that contain classes from `org.apache.maven` (as their condition). [[metadata-copy]] -==== Metadata copy +=== Metadata Copy The `metadataCopy` task provides additional options for manipulating the agent output after it finishes its job. @@ -625,7 +550,7 @@ You can set values for the following tags: the agent output for that stage. For example, if you want to copy only configuration files generated in tests, you can disable main stage. Also, if you want to copy only files generated in the main phase, you can disable the test stage. Therefore, if you skip both stages, `metadataCopy` will not be executed. [[configuration-reusing-config-from-parent]] -== Reusing configuration from a parent POM +== Reusing Configuration from a Parent POM The `` element can be combined between parent and children POMs. Suppose you have the following parent POM definition: @@ -669,7 +594,7 @@ In this case, the arguments that are passed to the `native-image` executable wil ---- [[testing-support]] -== Testing support +== Testing Support This plugin supports running tests on the https://junit.org/junit5/docs/current/user-guide/[JUnit Platform] as native images. This means that tests will be compiled and executed as native code. @@ -690,7 +615,7 @@ include::../../../../samples/java-application-with-tests/pom.xml[tag=native-plug Running the `./mvnw -Pnative test` will then build and run tests as native code. [[testing-support-version-compatibility]] -=== Version compatibility +=== Version Compatibility This plugin requires the Maven Surefire plugin 3.0.0 or higher to run tests as native code. @@ -726,7 +651,7 @@ If Maven Surefire is using an older version of the JUnit Platform, the build wil ---- [[testing-support-disabling]] -=== Disabling testing support +=== Disabling Testing Support If you wish to disable running tests on the JVM as well as tests as native code, you can invoke Maven with the `-DskipTests` flag. This flag is supported by Maven Surefire and Native Build Tools. @@ -740,85 +665,8 @@ For example, you might wish to disable only native testing support for use cases - Your library or application uses a testing framework that is not supported on the JUnit Platform. - You need to use the <> when running tests on the JVM but do not wish to run those same tests as native code. -[[long_classpath_and_shading_support]] -== Long classpath, @argument file and shading support - -Under Windows, https://github.com/graalvm/native-build-tools/issues/85[it is possible that the length of the classpath exceeds what the operating system supports] when invoking the CLI to build a native image. - -The plugin automatically passes arguments to the `native-image` tool from the argument file, instead of passing them directly. - -There is also the `native:write-args-file` goal that can be used to generate this argument file. -This can be useful in situations where `native-maven-plugin` is not available, for example, when running `native-image` in a Docker container. -The path to the arguments file is stored in the project properties under the key `graalvm.native-image.args-file`, so that other Maven plugins further in the lifecycle can use it. - -In case you are using a GraalVM version older than 21.3, you will however have to use a workaround, since the argument file wasn't supported. - -One option is to use a https://maven.apache.org/plugins/maven-shade-plugin[shaded JAR] and use it instead of individual JAR files on classpath. -For that, you need to setup the https://maven.apache.org/plugins/maven-shade-plugin[Maven Shade plugin]: - -[source,xml, indent=0, role="multi-language-sample"] -include::../../../../samples/java-application/pom.xml[tag=shade-plugin] - -If you need the testing support, add the JUnit Platform dependency explicitly: - -[source,xml, indent=0, role="multi-language-sample"] -include::../../../../samples/java-application-with-tests/pom.xml[tag=junit-platform-native-dependency] - -Then `native-maven-plugin` needs to be configured to use this JAR instead of the full classpath: - -[source,xml, indent=0, role="multi-language-sample"] -include::../../../../samples/java-application/pom.xml[tag=native-plugin] - -Depending on the other plugins your build uses (typically the Spring Boot plugin), you might have to configure, in addition, the main class: - -[source,xml, role="multi-language-sample"] ----- - - org.graalvm.buildtools - native-maven-plugin - ${native.buildtools.version} - - ${project.artifactId} - ${exec.mainClass} - - --no-fallback - - - - ${project.build.directory}/${project.artifactId}-${project.version}-shaded.jar - - -... ----- - -To be able to <>, you also need: - -- Create a _src/assembly/test-jar-with-dependencies.xml_ file with the following contents: - -[source,xml, indent=0, role="multi-language-sample"] -include::../../../../samples/java-application-with-tests/src/assembly/test-jar-with-dependencies.xml[tag=assembly] - -- Add the Maven Assembly plugin to your `native` profile: - -[source,xml, indent=0, role="multi-language-sample"] -include::../../../../samples/java-application-with-tests/pom.xml[tag=assembly-plugin] - -- Due to a limitation in Maven, you need to move the tests execution to the `integration-test` phase: - -[source,xml, indent=0, role="multi-language-sample"] -include::../../../../samples/java-application-with-tests/pom.xml[tag=native-plugin] - -Finally, you need to execute tests using the `integration-test` phase instead of `test`: - -[source,bash, role="multi-language-sample"] -```bash -./mvnw -Pnative integration-test -``` - -Refer to the https://maven.apache.org/plugins/maven-shade-plugin[Maven Shade plugin documentation] for more details on how to configure shading, and the https://maven.apache.org/plugins/maven-assembly-plugin[Maven Assembly plugin documentation] to tweak what to include in tests. - [[metadata-support]] -== GraalVM Reachability Metadata support +== GraalVM Reachability Metadata Support The plugin adds support for the https://github.com/oracle/graalvm-reachability-metadata/[GraalVM Reachability Metadata Repository]. This repository provides the https://www.graalvm.org/latest/reference-manual/native-image/metadata/[configuration] for libraries that do not support GraalVM Native Image. @@ -840,7 +688,7 @@ The repository is also published on Maven Central at the following coordinates: For example: `graalvm-reachability-metadata-{maven-plugin-version}-repository.zip`. ==== -=== Configuring the metadata repository +=== Configuring the Metadata Repository The plugin automatically downloads the configuration metadata from the official repository if you supply the version of the repository you want to use. @@ -891,7 +739,7 @@ This may be interesting if there is no specific metadata available for the parti include::../../../../samples/native-config-integration/pom.xml[tag=metadata-force-version] ---- -=== Adding metadata repository files +=== Adding Metadata Repository Files By default, reachability metadata is used only when your native image is being generated. In some situations, you may want to include the metadata directly inside your JAR file. @@ -907,6 +755,140 @@ Typically, the goal will be included in an execution step where, by default, it include::../../../../samples/native-config-integration/pom.xml[tag=add-reachability-metadata-execution] ---- +[[pgo-support]] +== Profile-Guided Optimization + +The plugin supports building optimized images with https://www.graalvm.org/latest/reference-manual/native-image/optimizations-and-performance/PGO/[Profile-Guided Optimization (PGO)] to improve performance and throughput. + +[NOTE] +==== +PGO is available in Oracle GraalVM. +==== + +The PGO workflow includes three steps: + +- First, generate a native image with instrumentation enabled. +- Next, run the image to gather profiling information. +- Then, create an optimized native image based on the profiles. + +To generate a binary with instrumentation enabled, pass the `--pgo-instrument` option to `native-image` using ``, and run the build command `./mvnw -Pnative package`. +To prevent overwriting a previously built native executable, we recommend either creating a separate Maven profile for each build or specifying a unique file name using the `` tag: + +[source,xml, role="multi-language-sample"] +---- + + instrumentedApp + + --pgo-instrument + + +---- + +Next, gather execution profiles by running the instrumented executable: + +[source,bash, role="multi-language-sample"] +---- +./target/instrumentedApp +---- + +By default, the _default.iprof_ file, if not specified otherwise, is generated alongside the native executable once the application is stopped. + +Lastly, build an optimized native image with profiles by passing the `--pgo` option in the plugin configuration: + +[source,xml, role="multi-language-sample"] +---- + + optimizedApp + + --pgo + + +---- + +If the profile file has the default name and location, it will be automatically used. +Alternatively, you can specify the file path as following: `--pgo=myprofile.iprof`. +If everything was done properly, you will see _"PGO: user-provided"_ in the native image build output. + +It is possible to include more than one profile, in which case you should rename the _.iprof_ files. +Learn more about PGO https://www.graalvm.org/reference-manual/native-image/optimizations-and-performance/PGO/basic-usage[on the website]. + +[[long_classpath_and_shading_support]] +== Long classpath, @argument File and Shading Support + +Under Windows, https://github.com/graalvm/native-build-tools/issues/85[it is possible that the length of the classpath exceeds what the operating system supports] when invoking the CLI to build a native image. + +The plugin automatically passes arguments to the `native-image` tool from the argument file, instead of passing them directly. + +There is also the `native:write-args-file` goal that can be used to generate this argument file. +This can be useful in situations where `native-maven-plugin` is not available, for example, when running `native-image` in a Docker container. +The path to the arguments file is stored in the project properties under the key `graalvm.native-image.args-file`, so that other Maven plugins further in the lifecycle can use it. + +In case you are using a GraalVM version older than 21.3, you will however have to use a workaround, since the argument file wasn't supported. + +One option is to use a https://maven.apache.org/plugins/maven-shade-plugin[shaded JAR] and use it instead of individual JAR files on classpath. +For that, you need to setup the https://maven.apache.org/plugins/maven-shade-plugin[Maven Shade plugin]: + +[source,xml, indent=0, role="multi-language-sample"] +include::../../../../samples/java-application/pom.xml[tag=shade-plugin] + +If you need the testing support, add the JUnit Platform dependency explicitly: + +[source,xml, indent=0, role="multi-language-sample"] +include::../../../../samples/java-application-with-tests/pom.xml[tag=junit-platform-native-dependency] + +Then `native-maven-plugin` needs to be configured to use this JAR instead of the full classpath: + +[source,xml, indent=0, role="multi-language-sample"] +include::../../../../samples/java-application/pom.xml[tag=native-plugin] + +Depending on the other plugins your build uses (typically the Spring Boot plugin), you might have to configure, in addition, the main class: + +[source,xml, role="multi-language-sample"] +---- + + org.graalvm.buildtools + native-maven-plugin + ${native.buildtools.version} + + ${project.artifactId} + ${exec.mainClass} + + --no-fallback + + + + ${project.build.directory}/${project.artifactId}-${project.version}-shaded.jar + + +... +---- + +To be able to <>, you also need: + +- Create a _src/assembly/test-jar-with-dependencies.xml_ file with the following contents: + +[source,xml, indent=0, role="multi-language-sample"] +include::../../../../samples/java-application-with-tests/src/assembly/test-jar-with-dependencies.xml[tag=assembly] + +- Add the Maven Assembly plugin to your `native` profile: + +[source,xml, indent=0, role="multi-language-sample"] +include::../../../../samples/java-application-with-tests/pom.xml[tag=assembly-plugin] + +- Due to a limitation in Maven, you need to move the tests execution to the `integration-test` phase: + +[source,xml, indent=0, role="multi-language-sample"] +include::../../../../samples/java-application-with-tests/pom.xml[tag=native-plugin] + +Finally, you need to execute tests using the `integration-test` phase instead of `test`: + +[source,bash, role="multi-language-sample"] +```bash +./mvnw -Pnative integration-test +``` + +Refer to the https://maven.apache.org/plugins/maven-shade-plugin[Maven Shade plugin documentation] for more details on how to configure shading, and the https://maven.apache.org/plugins/maven-assembly-plugin[Maven Assembly plugin documentation] to tweak what to include in tests. + [[javadocs]] == Javadocs