From bdf89e9377a8ee4c81e6e384fdad4b918c896c08 Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Fri, 16 Jun 2023 10:46:36 +0200 Subject: [PATCH 01/13] Bump repo version to 0.9.24-SNAPSHOT --- gradle/libs.versions.toml | 2 +- native-maven-plugin/reproducers/issue-144/pom.xml | 4 ++-- samples/java-application-with-custom-packaging/pom.xml | 2 +- samples/java-application-with-custom-tests/gradle.properties | 2 +- .../java-application-with-extra-sourceset/gradle.properties | 2 +- samples/java-application-with-reflection/gradle.properties | 2 +- samples/java-application-with-reflection/pom.xml | 4 ++-- samples/java-application-with-resources/gradle.properties | 2 +- samples/java-application-with-resources/pom.xml | 4 ++-- samples/java-application-with-tests/gradle.properties | 2 +- samples/java-application-with-tests/pom.xml | 4 ++-- samples/java-application/gradle.properties | 2 +- samples/java-application/pom.xml | 4 ++-- samples/java-library/gradle.properties | 2 +- samples/java-library/pom.xml | 4 ++-- samples/kotlin-application-with-tests/gradle.properties | 2 +- samples/metadata-repo-integration/gradle.properties | 2 +- samples/metadata-repo-integration/pom.xml | 4 ++-- samples/multi-project-with-tests/gradle.properties | 2 +- samples/multi-project-with-tests/pom.xml | 4 ++-- samples/native-config-integration/gradle.properties | 2 +- samples/native-config-integration/pom.xml | 4 ++-- 22 files changed, 31 insertions(+), 31 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 032d641eb..d78b2f863 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] # Project versions -nativeBuildTools = "0.9.23" +nativeBuildTools = "0.9.24-SNAPSHOT" metadataRepository = "0.3.2" # External dependencies diff --git a/native-maven-plugin/reproducers/issue-144/pom.xml b/native-maven-plugin/reproducers/issue-144/pom.xml index 2d3f35f1c..9b2340e03 100644 --- a/native-maven-plugin/reproducers/issue-144/pom.xml +++ b/native-maven-plugin/reproducers/issue-144/pom.xml @@ -56,8 +56,8 @@ 1.8 UTF-8 - 0.9.23 - 0.9.23 + 0.9.24-SNAPSHOT + 0.9.24-SNAPSHOT example-app org.graalvm.demo.Application diff --git a/samples/java-application-with-custom-packaging/pom.xml b/samples/java-application-with-custom-packaging/pom.xml index 06777d6f6..aca9f52b8 100644 --- a/samples/java-application-with-custom-packaging/pom.xml +++ b/samples/java-application-with-custom-packaging/pom.xml @@ -61,7 +61,7 @@ 3.3.4 org.graalvm.demo.Application netty - 0.9.23 + 0.9.24-SNAPSHOT diff --git a/samples/java-application-with-custom-tests/gradle.properties b/samples/java-application-with-custom-tests/gradle.properties index cb6aca2a7..6e3a33b8e 100644 --- a/samples/java-application-with-custom-tests/gradle.properties +++ b/samples/java-application-with-custom-tests/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.23 +native.gradle.plugin.version = 0.9.24-SNAPSHOT junit.jupiter.version = 5.8.1 junit.platform.version = 1.8.1 diff --git a/samples/java-application-with-extra-sourceset/gradle.properties b/samples/java-application-with-extra-sourceset/gradle.properties index cb6aca2a7..6e3a33b8e 100644 --- a/samples/java-application-with-extra-sourceset/gradle.properties +++ b/samples/java-application-with-extra-sourceset/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.23 +native.gradle.plugin.version = 0.9.24-SNAPSHOT junit.jupiter.version = 5.8.1 junit.platform.version = 1.8.1 diff --git a/samples/java-application-with-reflection/gradle.properties b/samples/java-application-with-reflection/gradle.properties index cb6aca2a7..6e3a33b8e 100644 --- a/samples/java-application-with-reflection/gradle.properties +++ b/samples/java-application-with-reflection/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.23 +native.gradle.plugin.version = 0.9.24-SNAPSHOT junit.jupiter.version = 5.8.1 junit.platform.version = 1.8.1 diff --git a/samples/java-application-with-reflection/pom.xml b/samples/java-application-with-reflection/pom.xml index d7076777b..c6478c491 100644 --- a/samples/java-application-with-reflection/pom.xml +++ b/samples/java-application-with-reflection/pom.xml @@ -52,8 +52,8 @@ 1.8 UTF-8 5.8.1 - 0.9.23 - 0.9.23 + 0.9.24-SNAPSHOT + 0.9.24-SNAPSHOT example-app org.graalvm.demo.Application diff --git a/samples/java-application-with-resources/gradle.properties b/samples/java-application-with-resources/gradle.properties index cb6aca2a7..6e3a33b8e 100644 --- a/samples/java-application-with-resources/gradle.properties +++ b/samples/java-application-with-resources/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.23 +native.gradle.plugin.version = 0.9.24-SNAPSHOT junit.jupiter.version = 5.8.1 junit.platform.version = 1.8.1 diff --git a/samples/java-application-with-resources/pom.xml b/samples/java-application-with-resources/pom.xml index 28a449291..3ae5e1c09 100644 --- a/samples/java-application-with-resources/pom.xml +++ b/samples/java-application-with-resources/pom.xml @@ -51,9 +51,9 @@ 1.8 UTF-8 - 0.9.23 + 0.9.24-SNAPSHOT 5.8.1 - 0.9.23 + 0.9.24-SNAPSHOT example-app org.graalvm.demo.Application diff --git a/samples/java-application-with-tests/gradle.properties b/samples/java-application-with-tests/gradle.properties index cb6aca2a7..6e3a33b8e 100644 --- a/samples/java-application-with-tests/gradle.properties +++ b/samples/java-application-with-tests/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.23 +native.gradle.plugin.version = 0.9.24-SNAPSHOT junit.jupiter.version = 5.8.1 junit.platform.version = 1.8.1 diff --git a/samples/java-application-with-tests/pom.xml b/samples/java-application-with-tests/pom.xml index 8ac90cdd8..de13703cf 100644 --- a/samples/java-application-with-tests/pom.xml +++ b/samples/java-application-with-tests/pom.xml @@ -52,8 +52,8 @@ 1.8 UTF-8 5.8.1 - 0.9.23 - 0.9.23 + 0.9.24-SNAPSHOT + 0.9.24-SNAPSHOT example-app org.graalvm.demo.Application diff --git a/samples/java-application/gradle.properties b/samples/java-application/gradle.properties index cb6aca2a7..6e3a33b8e 100644 --- a/samples/java-application/gradle.properties +++ b/samples/java-application/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.23 +native.gradle.plugin.version = 0.9.24-SNAPSHOT junit.jupiter.version = 5.8.1 junit.platform.version = 1.8.1 diff --git a/samples/java-application/pom.xml b/samples/java-application/pom.xml index e07a84f89..6033d683d 100644 --- a/samples/java-application/pom.xml +++ b/samples/java-application/pom.xml @@ -51,8 +51,8 @@ 1.8 UTF-8 - 0.9.23 - 0.9.23 + 0.9.24-SNAPSHOT + 0.9.24-SNAPSHOT example-app org.graalvm.demo.Application diff --git a/samples/java-library/gradle.properties b/samples/java-library/gradle.properties index cb6aca2a7..6e3a33b8e 100644 --- a/samples/java-library/gradle.properties +++ b/samples/java-library/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.23 +native.gradle.plugin.version = 0.9.24-SNAPSHOT junit.jupiter.version = 5.8.1 junit.platform.version = 1.8.1 diff --git a/samples/java-library/pom.xml b/samples/java-library/pom.xml index 28d0b13e3..821b58544 100644 --- a/samples/java-library/pom.xml +++ b/samples/java-library/pom.xml @@ -51,8 +51,8 @@ 1.8 UTF-8 - 0.9.23 - 0.9.23 + 0.9.24-SNAPSHOT + 0.9.24-SNAPSHOT java-library diff --git a/samples/kotlin-application-with-tests/gradle.properties b/samples/kotlin-application-with-tests/gradle.properties index cb6aca2a7..6e3a33b8e 100644 --- a/samples/kotlin-application-with-tests/gradle.properties +++ b/samples/kotlin-application-with-tests/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.23 +native.gradle.plugin.version = 0.9.24-SNAPSHOT junit.jupiter.version = 5.8.1 junit.platform.version = 1.8.1 diff --git a/samples/metadata-repo-integration/gradle.properties b/samples/metadata-repo-integration/gradle.properties index 5523f4ac2..dda35760e 100644 --- a/samples/metadata-repo-integration/gradle.properties +++ b/samples/metadata-repo-integration/gradle.properties @@ -1,4 +1,4 @@ -native.gradle.plugin.version = 0.9.23 +native.gradle.plugin.version = 0.9.24-SNAPSHOT h2.version = 2.1.210 netty.version = 4.1.80.Final logback.version = 1.4.4 diff --git a/samples/metadata-repo-integration/pom.xml b/samples/metadata-repo-integration/pom.xml index 50137fb47..766e2ce1c 100644 --- a/samples/metadata-repo-integration/pom.xml +++ b/samples/metadata-repo-integration/pom.xml @@ -51,8 +51,8 @@ 1.8 UTF-8 - 0.9.23 - 0.9.23 + 0.9.24-SNAPSHOT + 0.9.24-SNAPSHOT 2.1.210 4.1.80.Final 1.4.4 diff --git a/samples/multi-project-with-tests/gradle.properties b/samples/multi-project-with-tests/gradle.properties index cb6aca2a7..6e3a33b8e 100644 --- a/samples/multi-project-with-tests/gradle.properties +++ b/samples/multi-project-with-tests/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.23 +native.gradle.plugin.version = 0.9.24-SNAPSHOT junit.jupiter.version = 5.8.1 junit.platform.version = 1.8.1 diff --git a/samples/multi-project-with-tests/pom.xml b/samples/multi-project-with-tests/pom.xml index 92ce3726e..5082338f7 100644 --- a/samples/multi-project-with-tests/pom.xml +++ b/samples/multi-project-with-tests/pom.xml @@ -58,8 +58,8 @@ 1.8 UTF-8 5.8.1 - 0.9.23 - 0.9.23 + 0.9.24-SNAPSHOT + 0.9.24-SNAPSHOT example-app org.graalvm.demo.Application diff --git a/samples/native-config-integration/gradle.properties b/samples/native-config-integration/gradle.properties index cb6aca2a7..6e3a33b8e 100644 --- a/samples/native-config-integration/gradle.properties +++ b/samples/native-config-integration/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.23 +native.gradle.plugin.version = 0.9.24-SNAPSHOT junit.jupiter.version = 5.8.1 junit.platform.version = 1.8.1 diff --git a/samples/native-config-integration/pom.xml b/samples/native-config-integration/pom.xml index 1bb3b80e0..0b77d453b 100644 --- a/samples/native-config-integration/pom.xml +++ b/samples/native-config-integration/pom.xml @@ -51,8 +51,8 @@ 1.8 UTF-8 - 0.9.23 - 0.9.23 + 0.9.24-SNAPSHOT + 0.9.24-SNAPSHOT example-app org.graalvm.example.Application From f97d2b7a9adcec150c3a203b0af39ffd71afb607 Mon Sep 17 00:00:00 2001 From: Olya Gupalo Date: Wed, 28 Jun 2023 12:25:39 +0300 Subject: [PATCH 02/13] Update broken links --- README.md | 2 +- native-gradle-plugin/README.md | 6 ++++-- native-maven-plugin/README.md | 5 +++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a07e9488d..faf97aee9 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ![](https://github.com/graalvm/native-build-tools/actions/workflows/test-native-gradle-plugin.yml/badge.svg) ![](https://github.com/graalvm/native-build-tools/actions/workflows/test-native-maven-plugin.yml/badge.svg) -Repository which contains build tool plugins for interoperability with [GraalVM Native Image](https://www.graalvm.org/reference-manual/native-image/) +Repository which contains build tool plugins for interoperability with [GraalVM Native Image](https://www.graalvm.org/reference-manual/native-image/). End-user documentation about the plugins can be found [here](https://graalvm.github.io/native-build-tools/). diff --git a/native-gradle-plugin/README.md b/native-gradle-plugin/README.md index a98aae8f5..38e9a3ff4 100644 --- a/native-gradle-plugin/README.md +++ b/native-gradle-plugin/README.md @@ -5,11 +5,13 @@ Gradle plugin for GraalVM Native Image building End-user documentation about the plugins can be found [here](https://graalvm.github.io/native-build-tools/). ## Building -Building of plugin itself should be as simple as: + +This plugin can be built with this command: + ```bash ./gradlew publishToMavenLocal --no-parallel ``` In order to run testing part of this plugin you need to get (or build) corresponding `junit-platform-native` artifact. -*You can also take a look at CI workflow [here](../.github/workflows/native-gradle-plugin.yml).* +*You can also take a look at CI workflow [here](../.github/workflows/test-native-gradle-plugin.yml).* diff --git a/native-maven-plugin/README.md b/native-maven-plugin/README.md index 6cf7b7b85..ec32ec963 100644 --- a/native-maven-plugin/README.md +++ b/native-maven-plugin/README.md @@ -5,10 +5,11 @@ Maven plugin for GraalVM Native Image building End-user documentation about the plugins can be found [here](https://graalvm.github.io/native-build-tools/). ## Building -This plugin follows standard maven plugin conventions and as such can be built as: + +This plugin follows standard Maven plugin conventions and can be built with this command: ```shell ./gradlew publishAllPublicationsToCommonRepository ``` -*You can also take a look at CI workflow [here](../.github/workflows/native-maven-plugin.yml).* +*You can also take a look at CI workflow [here](../.github/workflows/test-native-maven-plugin.yml).* From 5252d66f533ef84d436d1f33f8e6b21ad1d648cf Mon Sep 17 00:00:00 2001 From: Olya Gupalo Date: Wed, 28 Jun 2023 13:14:35 +0300 Subject: [PATCH 03/13] Update GraalVM setup steps --- .../asciidoc/gradle-plugin-quickstart.adoc | 53 ++++++++++--------- docs/src/docs/asciidoc/gradle-plugin.adoc | 16 ++++-- docs/src/docs/asciidoc/index.adoc | 6 +-- .../asciidoc/maven-plugin-quickstart.adoc | 34 +++++++----- docs/src/docs/asciidoc/maven-plugin.adoc | 17 ++++-- 5 files changed, 78 insertions(+), 48 deletions(-) diff --git a/docs/src/docs/asciidoc/gradle-plugin-quickstart.adoc b/docs/src/docs/asciidoc/gradle-plugin-quickstart.adoc index 0e991e445..051b3bdb8 100644 --- a/docs/src/docs/asciidoc/gradle-plugin-quickstart.adoc +++ b/docs/src/docs/asciidoc/gradle-plugin-quickstart.adoc @@ -6,31 +6,36 @@ This guide shows how to get started with the <> - <<#build-a-native-executable-detecting-resources-with-the-agent,Build a Native Executable Detecting Resources with the Agent>> -[NOTE] ==== -.Sample Application - -You start by creating a **Fortune Teller** sample application that simulates the traditional -https://en.wikipedia.org/wiki/Fortune_(Unix)[fortune Unix program]. -The data for the fortune phrases is provided by https://github.com/your-fortune[YourFortune]. +The plugin requires that you <>. + +The easiest way to install GraalVM is to use the https://sdkman.io/jdks#grl[SDKMAN!]. +To install Oracle GraalVM for JDK 20 or JDK 17, run: +``` +sdk install java 20.0.1-graal +sdk install java 17.0.7-graal +``` +To install GraalVM Community Edition for JDK 20 or JDK 17, run: +``` +sdk install java 20.0.1-graalce +sdk install java 17.0.7-graalce +``` +GraalVM installation includes Native Image. +For other installation options, go to https://www.graalvm.org/downloads/[GraalVM Downloads]. ==== -==== -To use the Native Build Tools, install GraalVM with Native Image. -The easiest way to install GraalVM with Native Image is to use the https://github.com/graalvm/graalvm-jdk-downloader[GraalVM JDK Downloader]: +== Prepare a Demo Application -[source,bash] ----- -bash <(curl -sL https://get.graalvm.org/jdk) ----- ==== - -== Prepare a Demo Application +You start by creating a **Fortune Teller** sample application that simulates the traditional +https://en.wikipedia.org/wiki/Fortune_(Unix)[fortune Unix program]. +The data for the fortune phrases is provided by https://github.com/your-fortune[YourFortune]. +==== . Create a new Java project with *Gradle* using the following command (alternatively, you can use your IDE to generate a project): + @@ -38,7 +43,7 @@ bash <(curl -sL https://get.graalvm.org/jdk) ---- gradle init --project-name fortune-parent --type java-application --package demo --test-framework junit-jupiter --dsl groovy ---- -. Rename the default `app` directory to `fortune`, edit the `settings.gradle` file to replace `app` with `fortune`, then rename the default filename `App.java` to `Fortune.java`, and replace its contents with the following: +. Rename the default _app_ directory to _fortune_, edit the _settings.gradle_ file to replace `app` with `fortune`, then rename the default filename _App.java_ to _Fortune.java_, and replace its contents with the following: + [source,java] ---- @@ -118,9 +123,9 @@ public class Fortune { } } ---- -. Delete the `fortune/src/test/java` directory, you will add tests in a later stage. +. Delete the _fortune/src/test/java_ directory, you will add tests in a later stage. . Copy and paste the following file, -https://raw.githubusercontent.com/graalvm/graalvm-demos/master/fortune-demo/fortune/src/main/resources/fortunes.json[fortunes.json] under `fortune/src/main/resources/`. Your project tree should be: +https://raw.githubusercontent.com/graalvm/graalvm-demos/master/fortune-demo/fortune/src/main/resources/fortunes.json[fortunes.json] under _fortune/src/main/resources/_. Your project tree should be: + [source,shell] ---- @@ -250,7 +255,7 @@ graalvmNative { } ---- + -Another thing to note here: the plugin may not be able to properly detect the GraalVM installation, because of limitations in Gradle. By default, the plugin selects a Java 11 GraalVM Community Edition. If you want to use GraalVM Enterprise, or a particular version of GraalVM and Java, you need to explicitly tell this in plugin's configuration. For example: +Another thing to note here: the plugin may not be able to properly detect the GraalVM installation, because of limitations in Gradle. If you want to use Oracle GraalVM, or a particular version of GraalVM and Java, you need to explicitly tell this in plugin's configuration. For example: + [source,groovy,subs="verbatim,attributes", role="multi-language-sample"] ---- @@ -259,7 +264,7 @@ graalvmNative { main { javaLauncher = javaToolchains.launcherFor { languageVersion = JavaLanguageVersion.of(11) - vendor = JvmVendorSpec.matching("GraalVM Community") + vendor = JvmVendorSpec.matching("Oracle GraalVM") } } } @@ -273,7 +278,7 @@ graalvmNative { main { javaLauncher = javaToolchains.launcherFor { languageVersion = JavaLanguageVersion.of(11) - vendor = JvmVendorSpec.matching("GraalVM Community") + vendor = JvmVendorSpec.matching("Oracle GraalVM") } } } @@ -331,7 +336,7 @@ binaries.all { ---- It runs your application on the JVM with the agent, collects the metadata, and generates configuration files in the _$\{buildDir}/native/agent-output/$\{taskName}_ directory. . Copy the configuration files into the project's -`/META-INF/native-image` directory using the `metadataCopy` task: +_/META-INF/native-image_ directory using the `metadataCopy` task: + [source,shell] ---- @@ -393,7 +398,7 @@ The Gradle plugin for GraalVM Native Image can run https://junit.org/junit5/docs/current/user-guide/[JUnit Platform] tests on your native executable. This means that the tests will be compiled and run as native code. . Create the following test in the -`fortune/src/test/java/demo/FortuneTest.java` file: +_fortune/src/test/java/demo/FortuneTest.java_ file: + .fortune/src/test/java/demo/FortuneTest.java [source,java] diff --git a/docs/src/docs/asciidoc/gradle-plugin.adoc b/docs/src/docs/asciidoc/gradle-plugin.adoc index 30e5b1088..73bebd145 100644 --- a/docs/src/docs/asciidoc/gradle-plugin.adoc +++ b/docs/src/docs/asciidoc/gradle-plugin.adoc @@ -22,11 +22,21 @@ You can find full samples in https://github.com/graalvm/native-build-tools/tree/ ==== ==== -The plugin requires that you <>. -The easiest way to install GraalVM with Native Image is to use the https://github.com/graalvm/graalvm-jdk-downloader[GraalVM JDK Downloader]: +The plugin requires that you <>. + +The easiest way to install GraalVM is to use the https://sdkman.io/jdks#grl[SDKMAN!]. +To install Oracle GraalVM for JDK 20 or JDK 17, run: +``` +sdk install java 20.0.1-graal +sdk install java 17.0.7-graal +``` +To install GraalVM Community Edition for JDK 20 or JDK 17, run: ``` -bash <(curl -sL https://get.graalvm.org/jdk) +sdk install java 20.0.1-graalce +sdk install java 17.0.7-graalce ``` +GraalVM installation includes Native Image. +For other installation options, go to https://www.graalvm.org/downloads/[GraalVM Downloads]. ==== == Reference documentation diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index 45c3e3339..e05167835 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -3,7 +3,7 @@ The GraalVM team The {doctitle} project provides plugins for different build tools to add support for building and testing native applications written in Java (or any other language compiled to JVM bytecode). -Most notably, this is the official source for integrating with the https://www.graalvm.org/reference-manual/native-image/[GraalVM `native-image` tool]. +Most notably, this is the official source for integrating with the https://www.graalvm.org/reference-manual/native-image/[GraalVM Native Image]. Please refer to the following pages for build tool specific documentation: @@ -12,9 +12,9 @@ Please refer to the following pages for build tool specific documentation: This release of Native Build Tools ships with the GraalVM reachability metadata repository release {metadata-repository-version}. -If you are interested in contributing, please refer to our https://github.com/graalvm/native-build-tools[Git repository]. +If you are interested in contributing, please refer to the https://github.com/graalvm/native-build-tools[Git repository]. -If you are using alternative build systems, see <> +If you are using alternative build systems, see <>. [[changelog]] == Changelog diff --git a/docs/src/docs/asciidoc/maven-plugin-quickstart.adoc b/docs/src/docs/asciidoc/maven-plugin-quickstart.adoc index d5cb40a1a..42a904d1d 100644 --- a/docs/src/docs/asciidoc/maven-plugin-quickstart.adoc +++ b/docs/src/docs/asciidoc/maven-plugin-quickstart.adoc @@ -6,27 +6,33 @@ This guide shows how to get started with the <>. -You start by creating a **Fortune Teller** sample application that simulates the traditional -https://en.wikipedia.org/wiki/Fortune_(Unix)[fortune Unix program]. -The data for the fortune phrases is provided by https://github.com/your-fortune[YourFortune]. -==== - -==== -The plugin requires that you <>. -The easiest way to install GraalVM with Native Image is to use the https://github.com/graalvm/graalvm-jdk-downloader[GraalVM JDK Downloader]: +The easiest way to install GraalVM is to use the https://sdkman.io/jdks#grl[SDKMAN!]. +To install Oracle GraalVM for JDK 20 or JDK 17, run: +``` +sdk install java 20.0.1-graal +sdk install java 17.0.7-graal ``` -bash <(curl -sL https://get.graalvm.org/jdk) +To install GraalVM Community Edition for JDK 20 or JDK 17, run: ``` -It will then make use of Maven profiles to enable building and testing of native executables. +sdk install java 20.0.1-graalce +sdk install java 17.0.7-graalce +``` +GraalVM installation includes Native Image. +For other installation options, go to https://www.graalvm.org/downloads/[GraalVM Downloads]. ==== == Prepare a Demo Application -. Create a new Java project with *Maven* in your favorite IDE, called "Fortune", in the `demo` package. +==== +You start by creating a **Fortune Teller** sample application that simulates the traditional +https://en.wikipedia.org/wiki/Fortune_(Unix)[fortune Unix program]. +The data for the fortune phrases is provided by https://github.com/your-fortune[YourFortune]. +==== + +. Create a new Java project with *Maven* in your favorite IDE, called "Fortune", in the _demo_ package. Make sure to choose JUnit Jupiter as the test engine. The application should contain a sole Java file with the following content: + @@ -106,7 +112,7 @@ public class Fortune { } ---- . Copy and paste the following file, -https://raw.githubusercontent.com/graalvm/graalvm-demos/master/fortune-demo/fortune/src/main/resources/fortunes.json[fortunes.json] under `resources/`. Your project tree should be: +https://raw.githubusercontent.com/graalvm/graalvm-demos/master/fortune-demo/fortune/src/main/resources/fortunes.json[fortunes.json] under _resources/_. Your project tree should be: + [source,shell] ---- diff --git a/docs/src/docs/asciidoc/maven-plugin.adoc b/docs/src/docs/asciidoc/maven-plugin.adoc index aa592fbf3..2def0beaf 100644 --- a/docs/src/docs/asciidoc/maven-plugin.adoc +++ b/docs/src/docs/asciidoc/maven-plugin.adoc @@ -23,12 +23,21 @@ You can find full samples in https://github.com/graalvm/native-build-tools/tree/ ==== ==== -The plugin requires that you <>. -The easiest way to install GraalVM with Native Image is to use the https://github.com/graalvm/graalvm-jdk-downloader[GraalVM JDK Downloader]: +The plugin requires that you <>. + +The easiest way to install GraalVM is to use the https://sdkman.io/jdks#grl[SDKMAN!]. +To install Oracle GraalVM for JDK 20 or JDK 17, run: +``` +sdk install java 20.0.1-graal +sdk install java 17.0.7-graal +``` +To install GraalVM Community Edition for JDK 20 or JDK 17, run: ``` -bash <(curl -sL https://get.graalvm.org/jdk) +sdk install java 20.0.1-graalce +sdk install java 17.0.7-graalce ``` -It will then make use of Maven profiles to enable building and testing of native executables. +GraalVM installation includes Native Image. +For other installation options, go to https://www.graalvm.org/downloads/[GraalVM Downloads]. ==== [[configuration]] From 2e28f5c2554142aee82e6a15359f45efe2b2598e Mon Sep 17 00:00:00 2001 From: Olya Gupalo Date: Wed, 28 Jun 2023 14:10:11 +0300 Subject: [PATCH 04/13] Start sentences from a new line --- docs/src/docs/asciidoc/graalvm-setup.adoc | 51 +++++++----- .../asciidoc/gradle-plugin-quickstart.adoc | 78 ++++++++++--------- docs/src/docs/asciidoc/gradle-plugin.adoc | 9 +-- .../asciidoc/maven-plugin-quickstart.adoc | 64 ++++++++------- docs/src/docs/asciidoc/maven-plugin.adoc | 9 +-- 5 files changed, 108 insertions(+), 103 deletions(-) diff --git a/docs/src/docs/asciidoc/graalvm-setup.adoc b/docs/src/docs/asciidoc/graalvm-setup.adoc index 9c218ff6a..ac040e9d8 100644 --- a/docs/src/docs/asciidoc/graalvm-setup.adoc +++ b/docs/src/docs/asciidoc/graalvm-setup.adoc @@ -2,48 +2,63 @@ image:https://www.graalvm.org/resources/img/logo-colored.svg[GraalVM] -As a prerequisite for building with GraalVM Native Image, a GraalVM JDK is required and the `GRAALVM_HOME` and/or `JAVA_HOME` environment variables need to be set. +A prerequisite for using the Gradle or Maven plugin for GraalVM Native Image is to install GraalVM. +Follow the steps below to setup a GraalVM environment. -Following are the steps needed to obtain and setup a GraalVM environment. +[NOTE] +==== +This is just a quick overview, and users can consult the https://www.graalvm.org/docs/getting-started/[GraalVM Getting Started] before proceeding. +==== -NOTE: This is just a quick overview, and users can consult the https://www.graalvm.org/docs/getting-started/[GraalVM Getting Started section] before proceeding. +== 1. Download GraalVM -== 1. Obtaining distribution - -GraalVM distributions can be obtained from https://www.graalvm.org/downloads/[official website]. -Development builds might be available at `releases` section of https://github.com/graalvm/?q=graalvm-ce[official GraalVM Github page projects]. +The easiest way to download GraalVM is to use the https://sdkman.io/jdks[SDKMAN!]. +To install GraalVM for JDK 20 or JDK 17, run: +``` +sdk install java 20.0.1-graal +sdk install java 17.0.7-graal +``` +GraalVM installation includes Native Image. -== 2. Setting up environment variables +== 2. Set up Environment Variables -After obtaining GraalVM distribution environment variable `GRAALVM_HOME` should be set to point to it. +After obtaining a GraalVM distribution, set the `JAVA_HOME` and `PATH` environment variable. -This can be achieved using: +This can be achieved using this command: .Linux ```bash -export GRAALVM_HOME=/home/${current_user}/path/to/graalvm +export JAVA_HOME=/home/${current_user}/path/to/graalvm ``` .macOS ```bash -export GRAALVM_HOME=/Users/${current_user}/path/to/graalvm/Contents/Home +export JAVA_HOME=/Users/${current_user}/path/to/graalvm/Contents/Home ``` .Windows ```batch -setx /M GRAALVM_HOME "C:\path\to\graalvm" +setx /M JAVA_HOME "C:\path\to\graalvm" ``` -NOTE: Preferably user would also set `JAVA_HOME` variable in the same manner (by replacing `GRAALVM_HOME` with `JAVA_HOME` in previous commands). +In the same manner, set up the `PATH` environment variable: -== 3. `native-image` tool installation +.Linux +```bash +export JAVA_HOME=/home/${current_user}/path/to/graalvm/bin:$PATH +``` -.Linux / macOS +.macOS ```bash -$GRAALVM_HOME/bin/gu install native-image +export JAVA_HOME=/Users/${current_user}/path/to/graalvm/Contents/Home/bin:$PATH + ``` .Windows ```batch -%GRAALVM_HOME%/bin/gu install native-image +setx /M JAVA_HOME "C:\path\to\graalvm\bin;%PATH%" ``` + +For other installation options, go to the https://www.graalvm.org/downloads/[official website]. + +Development builds might be available at `releases` section of https://github.com/graalvm/?q=graalvm-ce[official GraalVM Github page projects]. \ No newline at end of file diff --git a/docs/src/docs/asciidoc/gradle-plugin-quickstart.adoc b/docs/src/docs/asciidoc/gradle-plugin-quickstart.adoc index 051b3bdb8..dbeb85d98 100644 --- a/docs/src/docs/asciidoc/gradle-plugin-quickstart.adoc +++ b/docs/src/docs/asciidoc/gradle-plugin-quickstart.adoc @@ -14,17 +14,12 @@ Two ways of building a native executable using the plugin will be demonstrated: ==== The plugin requires that you <>. -The easiest way to install GraalVM is to use the https://sdkman.io/jdks#grl[SDKMAN!]. -To install Oracle GraalVM for JDK 20 or JDK 17, run: +The easiest way to install GraalVM is to use the https://sdkman.io/jdks[SDKMAN!]. +To install GraalVM for JDK 20 or JDK 17, run: ``` sdk install java 20.0.1-graal sdk install java 17.0.7-graal ``` -To install GraalVM Community Edition for JDK 20 or JDK 17, run: -``` -sdk install java 20.0.1-graalce -sdk install java 17.0.7-graalce -``` GraalVM installation includes Native Image. For other installation options, go to https://www.graalvm.org/downloads/[GraalVM Downloads]. ==== @@ -125,7 +120,8 @@ public class Fortune { ---- . Delete the _fortune/src/test/java_ directory, you will add tests in a later stage. . Copy and paste the following file, -https://raw.githubusercontent.com/graalvm/graalvm-demos/master/fortune-demo/fortune/src/main/resources/fortunes.json[fortunes.json] under _fortune/src/main/resources/_. Your project tree should be: +https://raw.githubusercontent.com/graalvm/graalvm-demos/master/fortune-demo/fortune/src/main/resources/fortunes.json[fortunes.json] under _fortune/src/main/resources/_. +Your project tree should be: + [source,shell] ---- @@ -157,7 +153,8 @@ application { mainClass = 'demo.Fortune' } ---- -. Add explicit FasterXML Jackson dependencies that provide functionality to read and write JSON, data bindings (used in the demo application). Insert the following three lines in the `dependencies` section of _build.gradle_: +. Add explicit FasterXML Jackson dependencies that provide functionality to read and write JSON, data bindings (used in the demo application). +Insert the following three lines in the `dependencies` section of _build.gradle_: + [source,xml] ---- @@ -170,8 +167,7 @@ Also, remove the dependency on `guava` that will not be used. + The next steps demonstrate what you should do to enable the https://graalvm.github.io/native-build-tools/latest/gradle-plugin.html[Gradle Plugin for GraalVM Native Image]. -. Register the plugin. Add the following to -`plugins` section of your project’s _build.gradle_ file: +. Register the plugin. Add the following to `plugins` section of your project’s _build.gradle_ file: + [source,groovy,subs="verbatim,attributes", role="multi-language-sample"] ---- @@ -193,10 +189,11 @@ plugins { } ---- + -The `{gradle-plugin-version}` block pulls the latest plugin version. Replace it with a specific version if you prefer. -The plugin discovers which JAR files it needs to pass to the -`native-image` builder and what the executable main class should be. -. The plugin is not yet available on the Gradle Plugin Portal, so declare an additional plugin repository. Open the _settings.gradle_ file and replace the default content with this: +The `{gradle-plugin-version}` block pulls the latest plugin version. +Replace it with a specific version if you prefer. +The plugin discovers which JAR files it needs to pass to the `native-image` builder and what the executable main class should be. +. The plugin is not yet available on the Gradle Plugin Portal, so declare an additional plugin repository. +Open the _settings.gradle_ file and replace the default content with this: + [source,groovy,subs="verbatim,attributes", role="multi-language-sample"] ---- @@ -229,11 +226,11 @@ Note that the `pluginManagement {}` block must appear before any other statement [[build-a-native-executable-with-resources-autodetection]] == Build a Native Executable with Resources Autodetection -You can already build a native executable by running -`./gradlew nativeCompile` or run it directly by invoking -`./gradlew nativeRun`. However, at this stage, running the native executable will fail because this application requires additional metadata: you need to provide it with a list of resources to load. +You can already build a native executable by running `./gradlew nativeCompile` or run it directly by invoking `./gradlew nativeRun`. +However, at this stage, running the native executable will fail because this application requires additional metadata: you need to provide it with a list of resources to load. -. Instruct the plugin to automatically detect resources to be included in the native executable. Add this to your `build.gradle` file: +. Instruct the plugin to automatically detect resources to be included in the native executable. +Add this to your _build.gradle_ file: + [source,groovy,subs="verbatim,attributes", role="multi-language-sample"] ---- @@ -255,7 +252,9 @@ graalvmNative { } ---- + -Another thing to note here: the plugin may not be able to properly detect the GraalVM installation, because of limitations in Gradle. If you want to use Oracle GraalVM, or a particular version of GraalVM and Java, you need to explicitly tell this in plugin's configuration. For example: +Another thing to note here: the plugin may not be able to properly detect the GraalVM installation, because of limitations in Gradle. +If you want to use Oracle GraalVM, or a particular version of GraalVM and Java, you need to explicitly tell this in plugin's configuration. +For example: + [source,groovy,subs="verbatim,attributes", role="multi-language-sample"] ---- @@ -295,8 +294,7 @@ The workaround to this is to disable toolchain detection with this command `tool ./gradlew nativeRun ---- + -The native executable, named _fortune_, is created in the -_/fortune/build/native/nativeCompile_ directory. +The native executable, named _fortune_, is created in the _/fortune/build/native/nativeCompile_ directory. [start=3] . Run the native executable: + @@ -307,7 +305,8 @@ _/fortune/build/native/nativeCompile_ directory. The application starts and prints a random quote. -Configuring the `graalvmNative` plugin to automatically detect resources (`resources.autodetect()`) to be included in a binary is one way to make this example work. Using `resources.autodetect()` works because the application uses resources (_fortunes.json_) which are directly available in the `src/main/resources` location. +Configuring the `graalvmNative` plugin to automatically detect resources (`resources.autodetect()`) to be included in a binary is one way to make this example work. +Using `resources.autodetect()` works because the application uses resources (_fortunes.json_) which are directly available in the `src/main/resources` location. In the next section, the guide shows that you can use the tracing agent to do the same. @@ -316,11 +315,12 @@ In the next section, the guide shows that you can use the tracing agent to do th The Native Image Gradle plugin simplifies generation of the required metadata by injecting the https://graalvm.github.io/native-build-tools/latest/gradle-plugin.html#agent-support[ -tracing agent] automatically for you at compile time. To enable the agent, just pass the `-Pagent` option to any Gradle tasks that extends `JavaForkOptions` (for example, `test` or `run`). +tracing agent] automatically for you at compile time. +To enable the agent, just pass the `-Pagent` option to any Gradle tasks that extends `JavaForkOptions` (for example, `test` or `run`). The following steps illustrate how to collect metadata using the agent, and then build a native executable using that metadata. -. To demonstrate this approach, remove the `resources.autodetect()` block from your `build.gradle` file: +. To demonstrate this approach, remove the `resources.autodetect()` block from your _build.gradle_ file: + [source,shell] ---- @@ -335,8 +335,7 @@ binaries.all { ./gradlew -Pagent run ---- It runs your application on the JVM with the agent, collects the metadata, and generates configuration files in the _$\{buildDir}/native/agent-output/$\{taskName}_ directory. -. Copy the configuration files into the project's -_/META-INF/native-image_ directory using the `metadataCopy` task: +. Copy the configuration files into the project's _/META-INF/native-image_ directory using the `metadataCopy` task: + [source,shell] ---- @@ -349,8 +348,7 @@ _/META-INF/native-image_ directory using the `metadataCopy` task: ./gradlew nativeCompile ---- + -The native executable, named _fortune_, is created in the -_build/native/nativeCompile_ directory. +The native executable, named _fortune_, is created in the _build/native/nativeCompile_ directory. . Run the native executable: + [source,shell] @@ -390,12 +388,14 @@ graalvmNative { } ---- -The native executable then will be called `fortuneteller`. Notice how you can pass additional arguments to the `native-image` tool using the `buildArgs.add` syntax. +The native executable then will be called `fortuneteller`. +Notice how you can pass additional arguments to the `native-image` tool using the `buildArgs.add` syntax. == Add JUnit Testing The Gradle plugin for GraalVM Native Image can run -https://junit.org/junit5/docs/current/user-guide/[JUnit Platform] tests on your native executable. This means that the tests will be compiled and run as native code. +https://junit.org/junit5/docs/current/user-guide/[JUnit Platform] tests on your native executable. +This means that the tests will be compiled and run as native code. . Create the following test in the _fortune/src/test/java/demo/FortuneTest.java_ file: @@ -427,7 +427,8 @@ class FortuneTest { ./gradlew nativeTest ---- -The plugin runs tests on the JVM prior to running tests from the native executable. To disable testing support (which comes by default), add the following configuration to the _build.gradle_ file: +The plugin runs tests on the JVM prior to running tests from the native executable. +To disable testing support (which comes by default), add the following configuration to the _build.gradle_ file: [source,groovy,subs="verbatim,attributes", role="multi-language-sample"] ---- @@ -445,8 +446,7 @@ graalvmNative { == Run Tests with the Agent -If you need to test collecting metadata with the agent, add the -`-Pagent` option to the `test` and `nativeTest` task invocations: +If you need to test collecting metadata with the agent, add the `-Pagent` option to the `test` and `nativeTest` task invocations: . Run the tests on the JVM with the agent: + @@ -455,8 +455,8 @@ If you need to test collecting metadata with the agent, add the ./gradlew -Pagent test ---- + -It runs your application on the JVM with the agent, collects the metadata and uses it for testing on `native-image`. The generated configuration files (containing the metadata) can be found in the -_$\{buildDir}/native/agent-output/$\{taskName}_ directory. +It runs your application on the JVM with the agent, collects the metadata and uses it for testing on `native-image`. +The generated configuration files (containing the metadata) can be found in the _$\{buildDir}/native/agent-output/$\{taskName}_ directory. In this case, the plugin also substitutes `{output_dir}` in the agent options to point to this directory. . Build a native executable using the metadata collected by the agent: + @@ -467,8 +467,10 @@ In this case, the plugin also substitutes `{output_dir}` in the agent options to === Summary -The Gradle plugin for GraalVM Native Image adds support for building and testing native executables using the https://gradle.org[Gradle]. The plugin has many features, described in the +The Gradle plugin for GraalVM Native Image adds support for building and testing native executables using the https://gradle.org[Gradle]. +The plugin has many features, described in the https://graalvm.github.io/native-build-tools/latest/gradle-plugin.html[plugin reference documentation]. -Note that if your application does not call any classes dynamically at run time, the execution with the agent is needless. Your workflow, in that case, is just `./gradlew nativeRun`. \ No newline at end of file +Note that if your application does not call any classes dynamically at run time, the execution with the agent is needless. +Your workflow, in that case, is just `./gradlew nativeRun`. \ No newline at end of file diff --git a/docs/src/docs/asciidoc/gradle-plugin.adoc b/docs/src/docs/asciidoc/gradle-plugin.adoc index 73bebd145..7b56f8155 100644 --- a/docs/src/docs/asciidoc/gradle-plugin.adoc +++ b/docs/src/docs/asciidoc/gradle-plugin.adoc @@ -24,17 +24,12 @@ You can find full samples in https://github.com/graalvm/native-build-tools/tree/ ==== The plugin requires that you <>. -The easiest way to install GraalVM is to use the https://sdkman.io/jdks#grl[SDKMAN!]. -To install Oracle GraalVM for JDK 20 or JDK 17, run: +The easiest way to install GraalVM is to use the https://sdkman.io/jdks[SDKMAN!]. +To install GraalVM for JDK 20 or JDK 17, run: ``` sdk install java 20.0.1-graal sdk install java 17.0.7-graal ``` -To install GraalVM Community Edition for JDK 20 or JDK 17, run: -``` -sdk install java 20.0.1-graalce -sdk install java 17.0.7-graalce -``` GraalVM installation includes Native Image. For other installation options, go to https://www.graalvm.org/downloads/[GraalVM Downloads]. ==== diff --git a/docs/src/docs/asciidoc/maven-plugin-quickstart.adoc b/docs/src/docs/asciidoc/maven-plugin-quickstart.adoc index 42a904d1d..a1ef76e97 100644 --- a/docs/src/docs/asciidoc/maven-plugin-quickstart.adoc +++ b/docs/src/docs/asciidoc/maven-plugin-quickstart.adoc @@ -9,17 +9,12 @@ You will create a sample application, enable the plugin, add support for dynamic ==== The plugin requires that you <>. -The easiest way to install GraalVM is to use the https://sdkman.io/jdks#grl[SDKMAN!]. -To install Oracle GraalVM for JDK 20 or JDK 17, run: +The easiest way to install GraalVM is to use the https://sdkman.io/jdks[SDKMAN!]. +To install GraalVM for JDK 20 or JDK 17, run: ``` sdk install java 20.0.1-graal sdk install java 17.0.7-graal ``` -To install GraalVM Community Edition for JDK 20 or JDK 17, run: -``` -sdk install java 20.0.1-graalce -sdk install java 17.0.7-graalce -``` GraalVM installation includes Native Image. For other installation options, go to https://www.graalvm.org/downloads/[GraalVM Downloads]. ==== @@ -112,7 +107,8 @@ public class Fortune { } ---- . Copy and paste the following file, -https://raw.githubusercontent.com/graalvm/graalvm-demos/master/fortune-demo/fortune/src/main/resources/fortunes.json[fortunes.json] under _resources/_. Your project tree should be: +https://raw.githubusercontent.com/graalvm/graalvm-demos/master/fortune-demo/fortune/src/main/resources/fortunes.json[fortunes.json] under _resources/_. +Your project tree should be: + [source,shell] ---- @@ -138,7 +134,8 @@ https://raw.githubusercontent.com/graalvm/graalvm-demos/master/fortune-demo/fort ---- -. Add regular Maven plugins for building and assembling a Maven project into an executable JAR. Insert the following into the `build` section in the _pom.xml_ file: +. Add regular Maven plugins for building and assembling a Maven project into an executable JAR. +Insert the following into the `build` section in the _pom.xml_ file: + [source,xml] ---- @@ -226,10 +223,10 @@ https://raw.githubusercontent.com/graalvm/graalvm-demos/master/fortune-demo/fort ---- + -The statements "hardcoded" plugin versions and the entry point class to your application. The next steps demonstrate what you should do to enable the +The statements "hardcoded" plugin versions and the entry point class to your application. +The next steps demonstrate what you should do to enable the https://graalvm.github.io/native-build-tools/latest/maven-plugin.html[Maven plugin for GraalVM Native Image]. -. Register the Maven plugin for GraalVM Native Image, -`native-maven-plugin`, in the profile called `native` by adding the following to the _pom.xml_ file: +. Register the Maven plugin for GraalVM Native Image, `native-maven-plugin`, in the profile called `native` by adding the following to the _pom.xml_ file: + [source,xml] ---- @@ -271,15 +268,14 @@ https://graalvm.github.io/native-build-tools/latest/maven-plugin.html[Maven plug + It pulls the latest plugin version. Replace `${native.maven.plugin.version}` with a specific version if you prefer. The plugin discovers which JAR files it needs to pass to the -`native-image` builder and what the executable main class should be. With this plugin you can already build a native executable directly with Maven by running `mvn -Pnative package` (if your application does not call any methods reflectively at run time). +`native-image` builder and what the executable main class should be. +With this plugin you can already build a native executable directly with Maven by running `mvn -Pnative package` (if your application does not call any methods reflectively at run time). + -This demo application is a little more complicated than `HelloWorld`, and requires metadata before building a native executable. You do not have to configure anything manually: the plugin can generate the required metadata for you by -injecting the https://graalvm.github.io/native-build-tools/latest/maven-plugin.html#agent-support[tracing -agent] at package time. The agent is disabled by default, and can be enabled in project's _pom.xml_ file or via the command line. +This demo application is a little more complicated than `HelloWorld`, and requires metadata before building a native executable. You do not have to configure anything manually: the plugin can generate the required metadata for you by injecting the https://graalvm.github.io/native-build-tools/latest/maven-plugin.html#agent-support[tracing +agent] at package time. +The agent is disabled by default, and can be enabled in project's _pom.xml_ file or via the command line. -- To enable the agent via the _pom.xml_ file, specify -`true` in the `native-maven-plugin` plugin -configuration: +- To enable the agent via the _pom.xml_ file, specify `true` in the `native-maven-plugin` plugin configuration: + [source,xml] ---- @@ -292,7 +288,8 @@ configuration: - To enable the agent via the command line, pass the `-Dagent=true` option when running Maven. + So your next step is to run with the agent. -. Before running with the agent, register a separate Mojo execution in the `native` profile which allows forking the Java process. It is required to run your application with the agent. +. Before running with the agent, register a separate Mojo execution in the `native` profile which allows forking the Java process. +It is required to run your application with the agent. + [source,xml] ---- @@ -330,12 +327,12 @@ So your next step is to run with the agent. ---- + -Now you are all set to to build a native executable from a Java -application the plugin. +Now you are all set to to build a native executable from a Java application the plugin. == Build a Native Executable -. Compile the project on the JVM to create a runnable JAR with all dependencies. Open a terminal window and, from the root application directory, run: +. Compile the project on the JVM to create a runnable JAR with all dependencies. +Open a terminal window and, from the root application directory, run: + [source,shell] ---- @@ -348,7 +345,8 @@ mvn clean package mvn -Pnative -Dagent exec:exec@java-agent ---- + -The agent collects the metadata and generates the configuration files in a subdirectory of `target/native/agent-output`. Those files will be automatically used by the `native-image` tool if you pass the appropriate options. +The agent collects the metadata and generates the configuration files in a subdirectory of `target/native/agent-output`. +Those files will be automatically used by the `native-image` tool if you pass the appropriate options. . Now build a native executable with the Maven profile: + [source,shell] @@ -379,14 +377,14 @@ The executable's name is derived from the artifact ID, but you can specify any c mvn -Pnative exec:exec@native ---- -To see the benefits of running your application as a native executable, -`time` how long it takes and compare the results with running on the +To see the benefits of running your application as a native executable, `time` how long it takes and compare the results with running on the JVM. == Add JUnit Testing The Maven plugin for GraalVM Native Image can run -https://junit.org/junit5/docs/current/user-guide/[JUnit Platform] tests on a native executable. This means that tests will be compiled and executed as native code. +https://junit.org/junit5/docs/current/user-guide/[JUnit Platform] tests on a native executable. +This means that tests will be compiled and executed as native code. This plugin requires JUnit Platform 1.8 or higher and Maven Surefire 2.22.0 or higher to run tests on a native executable. @@ -401,8 +399,7 @@ This plugin requires JUnit Platform 1.8 or higher and Maven Surefire 2.22.0 or h ${native.maven.plugin.version} true ---- -. Add an explicit dependency on the `junit-platform-launcher` artifact -to the dependencies section of your native profile configuration as in +. Add an explicit dependency on the `junit-platform-launcher` artifact to the dependencies section of your native profile configuration as in the following example: + [source,xml] @@ -416,8 +413,7 @@ the following example: ---- -. Create the following test in the -`src/test/java/demo/FortuneTest.java` file: +. Create the following test in the `src/test/java/demo/FortuneTest.java` file: + .src/test/java/demo/FortuneTest.java [source,java] @@ -451,6 +447,8 @@ Run `-Pnative` profile will then build and run native tests. === Summary -The Maven plugin for GraalVM Native Image adds support for building and testing native executables using https://maven.apache.org/[Apache Maven™]. The plugin has many features, described in the <>. +The Maven plugin for GraalVM Native Image adds support for building and testing native executables using https://maven.apache.org/[Apache Maven™]. +The plugin has many features, described in the <>. -Note that if your application does not call any classes dynamically at run time, the execution with the agent is needless. Your workflow, in that case, is just `mvn clean -Pnative package`. +Note that if your application does not call any classes dynamically at run time, the execution with the agent is needless. +Your workflow, in that case, is just `mvn clean -Pnative package`. diff --git a/docs/src/docs/asciidoc/maven-plugin.adoc b/docs/src/docs/asciidoc/maven-plugin.adoc index 2def0beaf..7103c78da 100644 --- a/docs/src/docs/asciidoc/maven-plugin.adoc +++ b/docs/src/docs/asciidoc/maven-plugin.adoc @@ -25,17 +25,12 @@ You can find full samples in https://github.com/graalvm/native-build-tools/tree/ ==== The plugin requires that you <>. -The easiest way to install GraalVM is to use the https://sdkman.io/jdks#grl[SDKMAN!]. -To install Oracle GraalVM for JDK 20 or JDK 17, run: +The easiest way to install GraalVM is to use the https://sdkman.io/jdks[SDKMAN!]. +To install GraalVM for JDK 20 or JDK 17, run: ``` sdk install java 20.0.1-graal sdk install java 17.0.7-graal ``` -To install GraalVM Community Edition for JDK 20 or JDK 17, run: -``` -sdk install java 20.0.1-graalce -sdk install java 17.0.7-graalce -``` GraalVM installation includes Native Image. For other installation options, go to https://www.graalvm.org/downloads/[GraalVM Downloads]. ==== From 70dd88cb2cdaa9cbee61726be50522e9d49dad66 Mon Sep 17 00:00:00 2001 From: Olya Gupalo Date: Fri, 30 Jun 2023 12:07:58 +0300 Subject: [PATCH 05/13] Improve GraalVM setup guide --- docs/src/docs/asciidoc/graalvm-setup.adoc | 11 ++++++----- docs/src/docs/asciidoc/gradle-plugin-quickstart.adoc | 11 ++++++----- docs/src/docs/asciidoc/gradle-plugin.adoc | 11 ++++++----- docs/src/docs/asciidoc/maven-plugin-quickstart.adoc | 11 ++++++----- docs/src/docs/asciidoc/maven-plugin.adoc | 11 ++++++----- 5 files changed, 30 insertions(+), 25 deletions(-) diff --git a/docs/src/docs/asciidoc/graalvm-setup.adoc b/docs/src/docs/asciidoc/graalvm-setup.adoc index ac040e9d8..589a80c94 100644 --- a/docs/src/docs/asciidoc/graalvm-setup.adoc +++ b/docs/src/docs/asciidoc/graalvm-setup.adoc @@ -12,13 +12,14 @@ This is just a quick overview, and users can consult the https://www.graalvm.org == 1. Download GraalVM -The easiest way to download GraalVM is to use the https://sdkman.io/jdks[SDKMAN!]. -To install GraalVM for JDK 20 or JDK 17, run: +The easiest way to download GraalVM is to use the https://sdkman.io/jdks[SDKMAN!], simply run: + ``` -sdk install java 20.0.1-graal -sdk install java 17.0.7-graal +sdk install java 20.0.1-graal # for Oracle GraalVM for JDK 20 +sdk install java 17.0.7-graal # for Oracle GraalVM for JDK 17 + +# (use `graal-ce` instead of `graal` for GraalVM Community Edition) ``` -GraalVM installation includes Native Image. == 2. Set up Environment Variables diff --git a/docs/src/docs/asciidoc/gradle-plugin-quickstart.adoc b/docs/src/docs/asciidoc/gradle-plugin-quickstart.adoc index dbeb85d98..ff45706b6 100644 --- a/docs/src/docs/asciidoc/gradle-plugin-quickstart.adoc +++ b/docs/src/docs/asciidoc/gradle-plugin-quickstart.adoc @@ -14,13 +14,14 @@ Two ways of building a native executable using the plugin will be demonstrated: ==== The plugin requires that you <>. -The easiest way to install GraalVM is to use the https://sdkman.io/jdks[SDKMAN!]. -To install GraalVM for JDK 20 or JDK 17, run: +The easiest way to install GraalVM is to use the https://sdkman.io/jdks[SDKMAN!], simply run: + ``` -sdk install java 20.0.1-graal -sdk install java 17.0.7-graal +sdk install java 20.0.1-graal # for Oracle GraalVM for JDK 20 +sdk install java 17.0.7-graal # for Oracle GraalVM for JDK 17 + +# (use `graal-ce` instead of `graal` for GraalVM Community Edition) ``` -GraalVM installation includes Native Image. For other installation options, go to https://www.graalvm.org/downloads/[GraalVM Downloads]. ==== diff --git a/docs/src/docs/asciidoc/gradle-plugin.adoc b/docs/src/docs/asciidoc/gradle-plugin.adoc index 7b56f8155..5f50559be 100644 --- a/docs/src/docs/asciidoc/gradle-plugin.adoc +++ b/docs/src/docs/asciidoc/gradle-plugin.adoc @@ -24,13 +24,14 @@ You can find full samples in https://github.com/graalvm/native-build-tools/tree/ ==== The plugin requires that you <>. -The easiest way to install GraalVM is to use the https://sdkman.io/jdks[SDKMAN!]. -To install GraalVM for JDK 20 or JDK 17, run: +The easiest way to install GraalVM is to use the https://sdkman.io/jdks[SDKMAN!], simply run: + ``` -sdk install java 20.0.1-graal -sdk install java 17.0.7-graal +sdk install java 20.0.1-graal # for Oracle GraalVM for JDK 20 +sdk install java 17.0.7-graal # for Oracle GraalVM for JDK 17 + +# (use `graal-ce` instead of `graal` for GraalVM Community Edition) ``` -GraalVM installation includes Native Image. For other installation options, go to https://www.graalvm.org/downloads/[GraalVM Downloads]. ==== diff --git a/docs/src/docs/asciidoc/maven-plugin-quickstart.adoc b/docs/src/docs/asciidoc/maven-plugin-quickstart.adoc index a1ef76e97..6316a2006 100644 --- a/docs/src/docs/asciidoc/maven-plugin-quickstart.adoc +++ b/docs/src/docs/asciidoc/maven-plugin-quickstart.adoc @@ -9,13 +9,14 @@ You will create a sample application, enable the plugin, add support for dynamic ==== The plugin requires that you <>. -The easiest way to install GraalVM is to use the https://sdkman.io/jdks[SDKMAN!]. -To install GraalVM for JDK 20 or JDK 17, run: +The easiest way to install GraalVM is to use the https://sdkman.io/jdks[SDKMAN!], simply run: + ``` -sdk install java 20.0.1-graal -sdk install java 17.0.7-graal +sdk install java 20.0.1-graal # for Oracle GraalVM for JDK 20 +sdk install java 17.0.7-graal # for Oracle GraalVM for JDK 17 + +# (use `graal-ce` instead of `graal` for GraalVM Community Edition) ``` -GraalVM installation includes Native Image. For other installation options, go to https://www.graalvm.org/downloads/[GraalVM Downloads]. ==== diff --git a/docs/src/docs/asciidoc/maven-plugin.adoc b/docs/src/docs/asciidoc/maven-plugin.adoc index 7103c78da..4804a35bd 100644 --- a/docs/src/docs/asciidoc/maven-plugin.adoc +++ b/docs/src/docs/asciidoc/maven-plugin.adoc @@ -25,13 +25,14 @@ You can find full samples in https://github.com/graalvm/native-build-tools/tree/ ==== The plugin requires that you <>. -The easiest way to install GraalVM is to use the https://sdkman.io/jdks[SDKMAN!]. -To install GraalVM for JDK 20 or JDK 17, run: +The easiest way to install GraalVM is to use the https://sdkman.io/jdks[SDKMAN!], simply run: + ``` -sdk install java 20.0.1-graal -sdk install java 17.0.7-graal +sdk install java 20.0.1-graal # for Oracle GraalVM for JDK 20 +sdk install java 17.0.7-graal # for Oracle GraalVM for JDK 17 + +# (use `graal-ce` instead of `graal` for GraalVM Community Edition) ``` -GraalVM installation includes Native Image. For other installation options, go to https://www.graalvm.org/downloads/[GraalVM Downloads]. ==== From d1c4e4186ff6777b849512a754dd8527ad61066a Mon Sep 17 00:00:00 2001 From: Olya Gupalo Date: Fri, 7 Jul 2023 11:03:00 +0200 Subject: [PATCH 06/13] Send users to GraalVM website for setup instructions --- docs/src/docs/asciidoc/graalvm-setup.adoc | 65 ------------------- .../asciidoc/gradle-plugin-quickstart.adoc | 12 +--- docs/src/docs/asciidoc/gradle-plugin.adoc | 10 +-- .../asciidoc/maven-plugin-quickstart.adoc | 10 +-- docs/src/docs/asciidoc/maven-plugin.adoc | 10 +-- 5 files changed, 9 insertions(+), 98 deletions(-) delete mode 100644 docs/src/docs/asciidoc/graalvm-setup.adoc diff --git a/docs/src/docs/asciidoc/graalvm-setup.adoc b/docs/src/docs/asciidoc/graalvm-setup.adoc deleted file mode 100644 index 589a80c94..000000000 --- a/docs/src/docs/asciidoc/graalvm-setup.adoc +++ /dev/null @@ -1,65 +0,0 @@ -= Setting up GraalVM with Native Image Support - -image:https://www.graalvm.org/resources/img/logo-colored.svg[GraalVM] - -A prerequisite for using the Gradle or Maven plugin for GraalVM Native Image is to install GraalVM. -Follow the steps below to setup a GraalVM environment. - -[NOTE] -==== -This is just a quick overview, and users can consult the https://www.graalvm.org/docs/getting-started/[GraalVM Getting Started] before proceeding. -==== - -== 1. Download GraalVM - -The easiest way to download GraalVM is to use the https://sdkman.io/jdks[SDKMAN!], simply run: - -``` -sdk install java 20.0.1-graal # for Oracle GraalVM for JDK 20 -sdk install java 17.0.7-graal # for Oracle GraalVM for JDK 17 - -# (use `graal-ce` instead of `graal` for GraalVM Community Edition) -``` - -== 2. Set up Environment Variables - -After obtaining a GraalVM distribution, set the `JAVA_HOME` and `PATH` environment variable. - -This can be achieved using this command: - -.Linux -```bash -export JAVA_HOME=/home/${current_user}/path/to/graalvm -``` - -.macOS -```bash -export JAVA_HOME=/Users/${current_user}/path/to/graalvm/Contents/Home -``` - -.Windows -```batch -setx /M JAVA_HOME "C:\path\to\graalvm" -``` - -In the same manner, set up the `PATH` environment variable: - -.Linux -```bash -export JAVA_HOME=/home/${current_user}/path/to/graalvm/bin:$PATH -``` - -.macOS -```bash -export JAVA_HOME=/Users/${current_user}/path/to/graalvm/Contents/Home/bin:$PATH - -``` - -.Windows -```batch -setx /M JAVA_HOME "C:\path\to\graalvm\bin;%PATH%" -``` - -For other installation options, go to the https://www.graalvm.org/downloads/[official website]. - -Development builds might be available at `releases` section of https://github.com/graalvm/?q=graalvm-ce[official GraalVM Github page projects]. \ No newline at end of file diff --git a/docs/src/docs/asciidoc/gradle-plugin-quickstart.adoc b/docs/src/docs/asciidoc/gradle-plugin-quickstart.adoc index ff45706b6..a29608636 100644 --- a/docs/src/docs/asciidoc/gradle-plugin-quickstart.adoc +++ b/docs/src/docs/asciidoc/gradle-plugin-quickstart.adoc @@ -9,19 +9,13 @@ You will create a sample application, enable the plugin, add support for dynamic Two ways of building a native executable using the plugin will be demonstrated: - <<#build-a-native-executable-with-resources-autodetection,Build a Native Executable with Resources Autodetection>> -- <<#build-a-native-executable-detecting-resources-with-the-agent,Build a Native Executable Detecting Resources with the Agent>> +- <<#build-a-native-executable-detecting-resources-with-the-agent,Build a Native Executable Detecting Resources with the Agent>> ==== -The plugin requires that you <>. +The plugin requires that you https://www.graalvm.org/latest/docs/getting-started/[setup GraalVM]. -The easiest way to install GraalVM is to use the https://sdkman.io/jdks[SDKMAN!], simply run: +The easiest way to install GraalVM is to use the https://sdkman.io/jdks[SDKMAN!]. -``` -sdk install java 20.0.1-graal # for Oracle GraalVM for JDK 20 -sdk install java 17.0.7-graal # for Oracle GraalVM for JDK 17 - -# (use `graal-ce` instead of `graal` for GraalVM Community Edition) -``` For other installation options, go to https://www.graalvm.org/downloads/[GraalVM Downloads]. ==== diff --git a/docs/src/docs/asciidoc/gradle-plugin.adoc b/docs/src/docs/asciidoc/gradle-plugin.adoc index 5f50559be..6e2f0667e 100644 --- a/docs/src/docs/asciidoc/gradle-plugin.adoc +++ b/docs/src/docs/asciidoc/gradle-plugin.adoc @@ -22,16 +22,10 @@ You can find full samples in https://github.com/graalvm/native-build-tools/tree/ ==== ==== -The plugin requires that you <>. +The plugin requires that you https://www.graalvm.org/latest/docs/getting-started/[setup GraalVM]. -The easiest way to install GraalVM is to use the https://sdkman.io/jdks[SDKMAN!], simply run: +The easiest way to install GraalVM is to use the https://sdkman.io/jdks[SDKMAN!]. -``` -sdk install java 20.0.1-graal # for Oracle GraalVM for JDK 20 -sdk install java 17.0.7-graal # for Oracle GraalVM for JDK 17 - -# (use `graal-ce` instead of `graal` for GraalVM Community Edition) -``` For other installation options, go to https://www.graalvm.org/downloads/[GraalVM Downloads]. ==== diff --git a/docs/src/docs/asciidoc/maven-plugin-quickstart.adoc b/docs/src/docs/asciidoc/maven-plugin-quickstart.adoc index 6316a2006..960ead827 100644 --- a/docs/src/docs/asciidoc/maven-plugin-quickstart.adoc +++ b/docs/src/docs/asciidoc/maven-plugin-quickstart.adoc @@ -7,16 +7,10 @@ This guide shows how to get started with the <>. +The plugin requires that you https://www.graalvm.org/latest/docs/getting-started/[setup GraalVM]. -The easiest way to install GraalVM is to use the https://sdkman.io/jdks[SDKMAN!], simply run: +The easiest way to install GraalVM is to use the https://sdkman.io/jdks[SDKMAN!]. -``` -sdk install java 20.0.1-graal # for Oracle GraalVM for JDK 20 -sdk install java 17.0.7-graal # for Oracle GraalVM for JDK 17 - -# (use `graal-ce` instead of `graal` for GraalVM Community Edition) -``` For other installation options, go to https://www.graalvm.org/downloads/[GraalVM Downloads]. ==== diff --git a/docs/src/docs/asciidoc/maven-plugin.adoc b/docs/src/docs/asciidoc/maven-plugin.adoc index 4804a35bd..4e8e04bcf 100644 --- a/docs/src/docs/asciidoc/maven-plugin.adoc +++ b/docs/src/docs/asciidoc/maven-plugin.adoc @@ -23,16 +23,10 @@ You can find full samples in https://github.com/graalvm/native-build-tools/tree/ ==== ==== -The plugin requires that you <>. +The plugin requires that you https://www.graalvm.org/latest/docs/getting-started/[setup GraalVM]. -The easiest way to install GraalVM is to use the https://sdkman.io/jdks[SDKMAN!], simply run: +The easiest way to install GraalVM is to use the https://sdkman.io/jdks[SDKMAN!]. -``` -sdk install java 20.0.1-graal # for Oracle GraalVM for JDK 20 -sdk install java 17.0.7-graal # for Oracle GraalVM for JDK 17 - -# (use `graal-ce` instead of `graal` for GraalVM Community Edition) -``` For other installation options, go to https://www.graalvm.org/downloads/[GraalVM Downloads]. ==== From 6e4a273f196e83486867b1273e8ee38a5e48bc3a Mon Sep 17 00:00:00 2001 From: Abel Salgado Romero Date: Wed, 12 Jul 2023 16:59:15 +0200 Subject: [PATCH 07/13] Fix typos in reachability metadata gradle tasks descriptions (#463) * metadataCopy: replaces 'metdata' with 'metadata' * collectReachabilityMetadata: removes trailing dot to match all other task's descriptions --- .../java/org/graalvm/buildtools/gradle/NativeImagePlugin.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java index 00421aad5..6be798303 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java @@ -276,7 +276,7 @@ private void configureJavaProject(Project project, Provider project.getTasks().register("metadataCopy", MetadataCopyTask.class, task -> { task.setGroup(LifecycleBasePlugin.BUILD_GROUP); - task.setDescription("Copies metadata collected from tasks instrumented with the agent into target directories."); + task.setDescription("Copies metadata collected from tasks instrumented with the agent into target directories"); task.getInputTaskNames().set(graalExtension.getAgent().getMetadataCopy().getInputTaskNames()); task.getOutputDirectories().set(graalExtension.getAgent().getMetadataCopy().getOutputDirectories()); task.getMergeWithExisting().set(graalExtension.getAgent().getMetadataCopy().getMergeWithExisting()); @@ -285,7 +285,7 @@ private void configureJavaProject(Project project, Provider project.getTasks().register("collectReachabilityMetadata", CollectReachabilityMetadata.class, task -> { task.setGroup(LifecycleBasePlugin.BUILD_GROUP); - task.setDescription("Obtains native reachability metdata for the runtime classpath configuration"); + task.setDescription("Obtains native reachability metadata for the runtime classpath configuration"); task.setClasspath(project.getConfigurations().getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME)); }); From 298836496bc17f2f96514dde4eb455fc75ae24f6 Mon Sep 17 00:00:00 2001 From: ziyilin Date: Wed, 12 Jul 2023 22:59:53 +0800 Subject: [PATCH 08/13] Discover tests with `ClassLoader` other than `ImageClassLoader` (#445) Discover tests with another Java process JUnitPlatformFeature discovers tests before analysis. The discovery procsee will initialize some of the test classes when @RunWith, @Parameterized annotations are used. As they are loaded by the ImageClassloader, the initialization may cause eager class initialization error during native image building time. This commit lauches the test discovery in a another Java process in the JUnitPlatformFeature to make sure the test class initialization at discovery time won't affect the native image class initialization policy. --- .../junit/platform/JUnitPlatformFeature.java | 117 ++------ .../platform/NativeImageJUnitLauncher.java | 19 +- .../junit/platform/TestsDiscoveryHelper.java | 262 ++++++++++++++++++ .../platform/PlatformConfigProvider.java | 1 - .../config/vintage/VintageConfigProvider.java | 2 - .../buildtools/maven/NativeTestMojo.java | 11 + 6 files changed, 311 insertions(+), 101 deletions(-) create mode 100644 common/junit-platform-native/src/main/java/org/graalvm/junit/platform/TestsDiscoveryHelper.java diff --git a/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/JUnitPlatformFeature.java b/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/JUnitPlatformFeature.java index e9fc8c155..2882141a8 100644 --- a/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/JUnitPlatformFeature.java +++ b/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/JUnitPlatformFeature.java @@ -42,38 +42,21 @@ package org.graalvm.junit.platform; import org.graalvm.junit.platform.config.core.PluginConfigProvider; +import org.graalvm.nativeimage.ImageInfo; import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.hosted.Feature; import org.graalvm.nativeimage.hosted.RuntimeClassInitialization; -import org.junit.platform.engine.DiscoverySelector; -import org.junit.platform.engine.discovery.DiscoverySelectors; -import org.junit.platform.engine.discovery.UniqueIdSelector; -import org.junit.platform.engine.support.descriptor.ClassSource; -import org.junit.platform.launcher.Launcher; -import org.junit.platform.launcher.LauncherDiscoveryRequest; -import org.junit.platform.launcher.TestIdentifier; -import org.junit.platform.launcher.TestPlan; -import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder; -import org.junit.platform.launcher.core.LauncherFactory; -import org.junit.platform.launcher.listeners.UniqueIdTrackingListener; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.HashSet; +import java.util.ArrayList; import java.util.List; -import java.util.Optional; import java.util.ServiceLoader; import java.util.function.Consumer; -import java.util.stream.Collectors; -import java.util.stream.Stream; @SuppressWarnings("unused") public final class JUnitPlatformFeature implements Feature { - public final boolean debug = System.getProperty("debug") != null; + public static final boolean debug = System.getProperty(TestsDiscoveryHelper.DEBUG) != null; private static final NativeImageConfigurationImpl nativeImageConfigImpl = new NativeImageConfigurationImpl(); private final ServiceLoader extensionConfigProviders = ServiceLoader.load(PluginConfigProvider.class); @@ -86,65 +69,28 @@ public void duringSetup(DuringSetupAccess access) { @Override public void beforeAnalysis(BeforeAnalysisAccess access) { RuntimeClassInitialization.initializeAtBuildTime(NativeImageJUnitLauncher.class); - List classpathRoots = access.getApplicationClassPath(); - List selectors = getSelectors(classpathRoots); - - Launcher launcher = LauncherFactory.create(); - TestPlan testplan = discoverTestsAndRegisterTestClassesForReflection(launcher, selectors); - ImageSingletons.add(NativeImageJUnitLauncher.class, new NativeImageJUnitLauncher(launcher, testplan)); - } - - private List getSelectors(List classpathRoots) { - try { - Path outputDir = Paths.get(System.getProperty(UniqueIdTrackingListener.OUTPUT_DIR_PROPERTY_NAME)); - String prefix = System.getProperty(UniqueIdTrackingListener.OUTPUT_FILE_PREFIX_PROPERTY_NAME, - UniqueIdTrackingListener.DEFAULT_OUTPUT_FILE_PREFIX); - List selectors = readAllFiles(outputDir, prefix) - .map(DiscoverySelectors::selectUniqueId) - .collect(Collectors.toList()); - if (!selectors.isEmpty()) { - System.out.printf( - "[junit-platform-native] Running in 'test listener' mode using files matching pattern [%s*] " - + "found in folder [%s] and its subfolders.%n", - prefix, outputDir.toAbsolutePath()); - return selectors; + List> discoveredTests; + if (Boolean.parseBoolean(System.getProperty("isolateTestDiscovery"))) { + List discoveredTestNames = TestsDiscoveryHelper.launchTestDiscovery(debug, classpathRoots); + discoveredTests = new ArrayList<>(); + for (String discoveredTestName : discoveredTestNames) { + try { + discoveredTests.add(Class.forName(discoveredTestName, false, access.getApplicationClassLoader())); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } } - } catch (Exception ex) { - debug("Failed to read UIDs from UniqueIdTrackingListener output files: " + ex.getMessage()); + } else { + TestsDiscoveryHelper helper = new TestsDiscoveryHelper(debug, classpathRoots); + discoveredTests = helper.discoverTests(); } - - System.out.println("[junit-platform-native] Running in 'test discovery' mode. Note that this is a fallback mode."); - if (debug) { - classpathRoots.forEach(entry -> debug("Selecting classpath root: " + entry)); + for (Class discoveredTest : discoveredTests) { + registerTestClassForReflection(discoveredTest); } - return DiscoverySelectors.selectClasspathRoots(new HashSet<>(classpathRoots)); - } - - /** - * Use the JUnit Platform Launcher to discover tests and register classes - * for reflection. - */ - private TestPlan discoverTestsAndRegisterTestClassesForReflection(Launcher launcher, - List selectors) { - - LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request() - .selectors(selectors) - .build(); - TestPlan testPlan = launcher.discover(request); - - testPlan.getRoots().stream() - .flatMap(rootIdentifier -> testPlan.getDescendants(rootIdentifier).stream()) - .map(TestIdentifier::getSource) - .filter(Optional::isPresent) - .map(Optional::get) - .filter(ClassSource.class::isInstance) - .map(ClassSource.class::cast) - .map(ClassSource::getJavaClass) - .forEach(this::registerTestClassForReflection); - - return testPlan; + ImageSingletons.add(NativeImageJUnitLauncher.class, + new NativeImageJUnitLauncher(new TestsDiscoveryHelper(debug, classpathRoots))); } private void registerTestClassForReflection(Class clazz) { @@ -170,26 +116,11 @@ public static void debug(String format, Object... args) { } public static boolean debug() { - return ImageSingletons.lookup(JUnitPlatformFeature.class).debug; - } - - private Stream readAllFiles(Path dir, String prefix) throws IOException { - return findFiles(dir, prefix).map(outputFile -> { - try { - return Files.readAllLines(outputFile); - } catch (IOException ex) { - throw new UncheckedIOException(ex); - } - }).flatMap(List::stream); - } - - private static Stream findFiles(Path dir, String prefix) throws IOException { - if (!Files.exists(dir)) { - return Stream.empty(); + if (!ImageInfo.inImageCode()) { + return debug; + } else { + return ImageSingletons.lookup(JUnitPlatformFeature.class).debug; } - return Files.find(dir, Integer.MAX_VALUE, - (path, basicFileAttributes) -> (basicFileAttributes.isRegularFile() - && path.getFileName().toString().startsWith(prefix))); } } diff --git a/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/NativeImageJUnitLauncher.java b/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/NativeImageJUnitLauncher.java index c386fa1c5..b7858f26b 100644 --- a/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/NativeImageJUnitLauncher.java +++ b/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/NativeImageJUnitLauncher.java @@ -43,6 +43,8 @@ import org.graalvm.nativeimage.ImageInfo; import org.graalvm.nativeimage.ImageSingletons; +import org.graalvm.nativeimage.Platform; +import org.graalvm.nativeimage.Platforms; import org.junit.platform.launcher.Launcher; import org.junit.platform.launcher.TestExecutionListener; import org.junit.platform.launcher.TestPlan; @@ -59,11 +61,17 @@ public class NativeImageJUnitLauncher { static final String DEFAULT_OUTPUT_FOLDER = Paths.get("test-results-native").resolve("test").toString(); final Launcher launcher; - final TestPlan testPlan; + TestPlan testPlan; + final TestsDiscoveryHelper testsDiscoveryHelper; - public NativeImageJUnitLauncher(Launcher launcher, TestPlan testPlan) { - this.launcher = launcher; - this.testPlan = testPlan; + @Platforms(Platform.HOSTED_ONLY.class) + public NativeImageJUnitLauncher(TestsDiscoveryHelper testsDiscoveryHelper) { + this.testsDiscoveryHelper = testsDiscoveryHelper; + launcher = testsDiscoveryHelper.getLauncher(); + } + + private void discoverTests() { + testPlan = testsDiscoveryHelper.discoverTestPlan(); } public void registerTestExecutionListeners(TestExecutionListener testExecutionListener) { @@ -115,7 +123,8 @@ public static void main(String... args) { PrintWriter out = new PrintWriter(System.out); NativeImageJUnitLauncher launcher = ImageSingletons.lookup(NativeImageJUnitLauncher.class); - + //Discover the test plan at runtime. + launcher.discoverTests(); if (!silent) { out.println("JUnit Platform on Native Image - report"); out.println("----------------------------------------\n"); diff --git a/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/TestsDiscoveryHelper.java b/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/TestsDiscoveryHelper.java new file mode 100644 index 000000000..f0a2ca5fa --- /dev/null +++ b/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/TestsDiscoveryHelper.java @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.graalvm.junit.platform; + +import org.graalvm.compiler.serviceprovider.JavaVersionUtil; +import org.junit.platform.engine.DiscoverySelector; +import org.junit.platform.engine.discovery.DiscoverySelectors; +import org.junit.platform.engine.discovery.UniqueIdSelector; +import org.junit.platform.engine.support.descriptor.ClassSource; +import org.junit.platform.launcher.Launcher; +import org.junit.platform.launcher.LauncherDiscoveryRequest; +import org.junit.platform.launcher.TestIdentifier; +import org.junit.platform.launcher.TestPlan; +import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder; +import org.junit.platform.launcher.core.LauncherFactory; +import org.junit.platform.launcher.listeners.UniqueIdTrackingListener; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class TestsDiscoveryHelper { + public static final String TESTDISCOVERY_OUTPUT = "testdiscovery.output"; + public static final String DEBUG = "debug"; + + private List selectors; + private Launcher launcher = LauncherFactory.create(); + private TestPlan testPlan; + + public static void main(String[] args) throws IOException { + if (args.length == 0) { + throw new RuntimeException("Must set classpath roots"); + } + List list = Arrays.stream(args[0].split(File.pathSeparator)).map(s -> Paths.get(s)).collect(Collectors.toList()); + TestsDiscoveryHelper testsDiscoveryHelper = new TestsDiscoveryHelper(Boolean.parseBoolean(System.getProperty(DEBUG, "false")), list); + List> ret = testsDiscoveryHelper.discoverTests(); + String outputPath = System.getProperty(TESTDISCOVERY_OUTPUT); + String output = ret.stream().map(c -> c.getName()).reduce((s1, s2) -> s1 + "\n" + s2).get(); + try (FileWriter fw = new FileWriter(new File(outputPath))) { + fw.write(output); + fw.flush(); + } catch (IOException e) { + throw e; + } + } + + public TestsDiscoveryHelper(boolean debug, List classpathRoots) { + selectors = getSelectors(debug, classpathRoots); + } + + public Launcher getLauncher() { + return launcher; + } + + public TestPlan discoverTestPlan() { + LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request() + .selectors(selectors) + .build(); + testPlan = launcher.discover(request); + return testPlan; + } + + /** + * Launch another Java process to discover tests to avoid unintended class initialization for native image + * building. + * @param debug is debug turned on + * @param classpathRoots class paths + * @return a list of discovered test names + */ + public static List launchTestDiscovery(boolean debug, List classpathRoots) { + int discoverResult; + Path resultFile; + try { + resultFile = Files.createTempFile("native-image-build-tool-ret-", ""); + ProcessBuilder pb = new ProcessBuilder(); + + String javaHome = System.getProperty("java.home"); + List command = new ArrayList<>(); + command.add(javaHome + File.separator + "bin" + File.separator + "java"); + StringBuilder args = new StringBuilder(" "); + String debugPort = System.getProperty("isolateTestDiscoveryDebugPort"); + if (debugPort != null && !debugPort.equals("-1")) { + args.append("-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address="); + if (JavaVersionUtil.JAVA_SPEC >= 9) { + args.append("*:"); + } + args.append(debugPort).append(" "); + } + + // Use the same system properties as current Java process + System.getProperties().forEach((k, v) -> { + if (!k.equals("line.separator") && !k.equals("java.system.class.loader") + && !((String) k).startsWith("jdk.module")) { + args.append("-D" + k + "=\"" + v + "\"").append(" "); + } + }); + args.append("-D" + TESTDISCOVERY_OUTPUT + "=" + resultFile).append(" "); + args.append("-D" + DEBUG + "=" + debug).append(" "); + args.append("-cp").append(" "); + String cp = classpathRoots.stream().map(p -> p.toString()).collect(Collectors.joining(File.pathSeparator)); + args.append(cp).append(" "); + args.append(TestsDiscoveryHelper.class.getName()).append(" "); + args.append(cp).append(" "); + + // Run the new process in the form of "java @argfile" + Path argFile = Files.createTempFile("native-image-build-tool-args-", ""); + try (FileWriter fw = new FileWriter(argFile.toFile())) { + fw.write(args.toString()); + fw.flush(); + } catch (IOException e) { + throw e; + } + command.add("@" + argFile.toString()); + pb.command(command); + Map env = pb.environment(); + if (env == null) { + env = new HashMap<>(); + } + env.putAll(System.getenv()); + + pb.inheritIO(); + System.out.println("[junit-platform-native] Launching tests discovery in a a separated JVM."); + Process process = pb.start(); + discoverResult = process.waitFor(); + } catch (IOException | InterruptedException e) { + throw new RuntimeException(e); + } + // The discovery results are written in the file, read it. + List ret; + if (discoverResult == 0) { + try { + ret = new ArrayList<>(); + BufferedReader br = new BufferedReader(new FileReader(resultFile.toFile())); + String line; + while ((line = br.readLine()) != null) { + ret.add(line); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } else { + throw new RuntimeException("Discover test plan was failed."); + } + return ret; + } + + /** + * Use the JUnit Platform Launcher to discover tests and register classes + * for reflection. + * + * @return a List of discovered junit test classes + */ + public List> discoverTests() { + discoverTestPlan(); + return testPlan.getRoots().stream() + .flatMap(rootIdentifier -> testPlan.getDescendants(rootIdentifier).stream()) + .map(TestIdentifier::getSource) + .filter(Optional::isPresent) + .map(Optional::get) + .filter(ClassSource.class::isInstance) + .map(ClassSource.class::cast) + .map(cs -> cs.getJavaClass()).collect(Collectors.toList()); + } + + private List getSelectors(boolean debug, List classpathRoots) { + try { + Path outputDir = Paths.get(System.getProperty(UniqueIdTrackingListener.OUTPUT_DIR_PROPERTY_NAME)); + String prefix = System.getProperty(UniqueIdTrackingListener.OUTPUT_FILE_PREFIX_PROPERTY_NAME, + UniqueIdTrackingListener.DEFAULT_OUTPUT_FILE_PREFIX); + List selectors = readAllFiles(outputDir, prefix) + .map(DiscoverySelectors::selectUniqueId) + .collect(Collectors.toList()); + if (!selectors.isEmpty()) { + System.out.printf( + "[junit-platform-native] Running in 'test listener' mode using files matching pattern [%s*] " + + "found in folder [%s] and its subfolders.%n", + prefix, outputDir.toAbsolutePath()); + return selectors; + } + } catch (Exception ex) { + JUnitPlatformFeature.debug("Failed to read UIDs from UniqueIdTrackingListener output files: " + ex.getMessage()); + } + + System.out.println("[junit-platform-native] Running in 'test discovery' mode. Note that this is a fallback mode."); + if (debug) { + classpathRoots.forEach(entry -> JUnitPlatformFeature.debug("Selecting classpath root: " + entry)); + } + return DiscoverySelectors.selectClasspathRoots(new HashSet<>(classpathRoots)); + } + + private Stream readAllFiles(Path dir, String prefix) throws IOException { + return findFiles(dir, prefix).map(outputFile -> { + try { + return Files.readAllLines(outputFile); + } catch (IOException ex) { + throw new UncheckedIOException(ex); + } + }).flatMap(List::stream); + } + + private static Stream findFiles(Path dir, String prefix) throws IOException { + if (!Files.exists(dir)) { + return Stream.empty(); + } + return Files.find(dir, Integer.MAX_VALUE, + (path, basicFileAttributes) -> (basicFileAttributes.isRegularFile() + && path.getFileName().toString().startsWith(prefix))); + } +} diff --git a/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/config/platform/PlatformConfigProvider.java b/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/config/platform/PlatformConfigProvider.java index d67cd5d77..a07344f1c 100644 --- a/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/config/platform/PlatformConfigProvider.java +++ b/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/config/platform/PlatformConfigProvider.java @@ -58,7 +58,6 @@ public void onLoad(NativeImageConfiguration config) { "org.junit.platform.launcher.core.LauncherConfigurationParameters", "org.junit.platform.commons.logging.LoggerFactory", "org.junit.platform.engine.UniqueIdFormat", - "org.junit.platform.commons.util.ReflectionUtils", // https://github.com/graalvm/native-build-tools/issues/300 "org.junit.platform.reporting.open.xml.OpenTestReportGeneratingListener" }; diff --git a/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/config/vintage/VintageConfigProvider.java b/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/config/vintage/VintageConfigProvider.java index b5a6eec98..c2cf51dbe 100644 --- a/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/config/vintage/VintageConfigProvider.java +++ b/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/config/vintage/VintageConfigProvider.java @@ -53,8 +53,6 @@ public void onLoad(NativeImageConfiguration config) { "org.junit.vintage.engine.support.UniqueIdReader", "org.junit.vintage.engine.support.UniqueIdStringifier", "org.junit.runner.Description", - "org.junit.runners.BlockJUnit4ClassRunner", - "org.junit.runners.JUnit4", /* Workaround until we can register serializable classes from a native-image feature */ "org.junit.runner.Result" }; diff --git a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeTestMojo.java b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeTestMojo.java index aaf95fbe7..809eebd26 100644 --- a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeTestMojo.java +++ b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeTestMojo.java @@ -84,6 +84,12 @@ public class NativeTestMojo extends AbstractNativeImageMojo { @Parameter(property = "skipNativeTests", defaultValue = "false") private boolean skipNativeTests; + @Parameter(property = "isolateTestDiscovery", defaultValue = "true") + private boolean isolateTestDiscovery; + + @Parameter(property = "isolateTestDiscoveryDebugPort", defaultValue = "-1") + private int isolateTestDiscoveryDebugPort; + @Override protected void populateApplicationClasspath() throws MojoExecutionException { super.populateApplicationClasspath(); @@ -138,6 +144,11 @@ public void execute() throws MojoExecutionException { configureEnvironment(); buildArgs.add("--features=org.graalvm.junit.platform.JUnitPlatformFeature"); + buildArgs.add("-DisolateTestDiscovery=" + isolateTestDiscovery); + if (isolateTestDiscovery) { + buildArgs.add("-DisolateTestDiscoveryDebugPort=" + isolateTestDiscoveryDebugPort); + } + if (systemProperties == null) { systemProperties = new HashMap<>(); } From 1c4c1743b1cced0d8216d06b59c9b5b9d729133d Mon Sep 17 00:00:00 2001 From: ziyilin Date: Wed, 12 Jul 2023 23:00:20 +0800 Subject: [PATCH 09/13] Keep same classpath order as surefire (#450) The elements' order on the classpath for native-image building must be consistent with the testing time when the graalvm agent is enabled to record the native image configurations. --- .../maven/AbstractNativeImageMojo.java | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java index cdd58e386..10d0f2aea 100644 --- a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java +++ b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java @@ -69,10 +69,12 @@ import java.nio.file.Files; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashSet; import java.util.List; import java.util.Collections; import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -321,15 +323,17 @@ protected void warnIfWrongMetaInfLayout(Path jarFilePath, Artifact artifact) thr protected void addDependenciesToClasspath() throws MojoExecutionException { configureMetadataRepository(); - for (Artifact dependency : project.getArtifacts().stream() - .filter(artifact -> getDependencyScopes().contains(artifact.getScope())) - .collect(Collectors.toSet())) { - addArtifactToClasspath(dependency); - maybeAddDependencyMetadata(dependency, file -> { - buildArgs.add("--exclude-config"); - buildArgs.add(Pattern.quote(dependency.getFile().getAbsolutePath())); - buildArgs.add("^/META-INF/native-image/"); - }); + Set collected = new HashSet<>(); + // Must keep classpath order is the same with surefire test + for (Artifact dependency : project.getArtifacts()) { + if (getDependencyScopes().contains(dependency.getScope()) && collected.add(dependency)) { + addArtifactToClasspath(dependency); + maybeAddDependencyMetadata(dependency, file -> { + buildArgs.add("--exclude-config"); + buildArgs.add(Pattern.quote(dependency.getFile().getAbsolutePath())); + buildArgs.add("^/META-INF/native-image/"); + }); + } } } From 7bdab7aeb4b72bf10a04bd6611ed577eea05767c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Champeau?= Date: Thu, 20 Jul 2023 17:22:48 +0200 Subject: [PATCH 10/13] Revert "Discover tests with `ClassLoader` other than `ImageClassLoader`" (#470) Revert "Discover tests with `ClassLoader` other than `ImageClassLoader` (#445)" This reverts commit 298836496bc17f2f96514dde4eb455fc75ae24f6. --- .../junit/platform/JUnitPlatformFeature.java | 117 ++++++-- .../platform/NativeImageJUnitLauncher.java | 19 +- .../junit/platform/TestsDiscoveryHelper.java | 262 ------------------ .../platform/PlatformConfigProvider.java | 1 + .../config/vintage/VintageConfigProvider.java | 2 + .../buildtools/maven/NativeTestMojo.java | 11 - 6 files changed, 101 insertions(+), 311 deletions(-) delete mode 100644 common/junit-platform-native/src/main/java/org/graalvm/junit/platform/TestsDiscoveryHelper.java diff --git a/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/JUnitPlatformFeature.java b/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/JUnitPlatformFeature.java index 2882141a8..e9fc8c155 100644 --- a/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/JUnitPlatformFeature.java +++ b/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/JUnitPlatformFeature.java @@ -42,21 +42,38 @@ package org.graalvm.junit.platform; import org.graalvm.junit.platform.config.core.PluginConfigProvider; -import org.graalvm.nativeimage.ImageInfo; import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.hosted.Feature; import org.graalvm.nativeimage.hosted.RuntimeClassInitialization; +import org.junit.platform.engine.DiscoverySelector; +import org.junit.platform.engine.discovery.DiscoverySelectors; +import org.junit.platform.engine.discovery.UniqueIdSelector; +import org.junit.platform.engine.support.descriptor.ClassSource; +import org.junit.platform.launcher.Launcher; +import org.junit.platform.launcher.LauncherDiscoveryRequest; +import org.junit.platform.launcher.TestIdentifier; +import org.junit.platform.launcher.TestPlan; +import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder; +import org.junit.platform.launcher.core.LauncherFactory; +import org.junit.platform.launcher.listeners.UniqueIdTrackingListener; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Files; import java.nio.file.Path; -import java.util.ArrayList; +import java.nio.file.Paths; +import java.util.HashSet; import java.util.List; +import java.util.Optional; import java.util.ServiceLoader; import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; @SuppressWarnings("unused") public final class JUnitPlatformFeature implements Feature { - public static final boolean debug = System.getProperty(TestsDiscoveryHelper.DEBUG) != null; + public final boolean debug = System.getProperty("debug") != null; private static final NativeImageConfigurationImpl nativeImageConfigImpl = new NativeImageConfigurationImpl(); private final ServiceLoader extensionConfigProviders = ServiceLoader.load(PluginConfigProvider.class); @@ -69,28 +86,65 @@ public void duringSetup(DuringSetupAccess access) { @Override public void beforeAnalysis(BeforeAnalysisAccess access) { RuntimeClassInitialization.initializeAtBuildTime(NativeImageJUnitLauncher.class); + List classpathRoots = access.getApplicationClassPath(); - List> discoveredTests; - if (Boolean.parseBoolean(System.getProperty("isolateTestDiscovery"))) { - List discoveredTestNames = TestsDiscoveryHelper.launchTestDiscovery(debug, classpathRoots); - discoveredTests = new ArrayList<>(); - for (String discoveredTestName : discoveredTestNames) { - try { - discoveredTests.add(Class.forName(discoveredTestName, false, access.getApplicationClassLoader())); - } catch (ClassNotFoundException e) { - throw new RuntimeException(e); - } + List selectors = getSelectors(classpathRoots); + + Launcher launcher = LauncherFactory.create(); + TestPlan testplan = discoverTestsAndRegisterTestClassesForReflection(launcher, selectors); + ImageSingletons.add(NativeImageJUnitLauncher.class, new NativeImageJUnitLauncher(launcher, testplan)); + } + + private List getSelectors(List classpathRoots) { + try { + Path outputDir = Paths.get(System.getProperty(UniqueIdTrackingListener.OUTPUT_DIR_PROPERTY_NAME)); + String prefix = System.getProperty(UniqueIdTrackingListener.OUTPUT_FILE_PREFIX_PROPERTY_NAME, + UniqueIdTrackingListener.DEFAULT_OUTPUT_FILE_PREFIX); + List selectors = readAllFiles(outputDir, prefix) + .map(DiscoverySelectors::selectUniqueId) + .collect(Collectors.toList()); + if (!selectors.isEmpty()) { + System.out.printf( + "[junit-platform-native] Running in 'test listener' mode using files matching pattern [%s*] " + + "found in folder [%s] and its subfolders.%n", + prefix, outputDir.toAbsolutePath()); + return selectors; } - } else { - TestsDiscoveryHelper helper = new TestsDiscoveryHelper(debug, classpathRoots); - discoveredTests = helper.discoverTests(); + } catch (Exception ex) { + debug("Failed to read UIDs from UniqueIdTrackingListener output files: " + ex.getMessage()); } - for (Class discoveredTest : discoveredTests) { - registerTestClassForReflection(discoveredTest); + + System.out.println("[junit-platform-native] Running in 'test discovery' mode. Note that this is a fallback mode."); + if (debug) { + classpathRoots.forEach(entry -> debug("Selecting classpath root: " + entry)); } + return DiscoverySelectors.selectClasspathRoots(new HashSet<>(classpathRoots)); + } + + /** + * Use the JUnit Platform Launcher to discover tests and register classes + * for reflection. + */ + private TestPlan discoverTestsAndRegisterTestClassesForReflection(Launcher launcher, + List selectors) { + + LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request() + .selectors(selectors) + .build(); - ImageSingletons.add(NativeImageJUnitLauncher.class, - new NativeImageJUnitLauncher(new TestsDiscoveryHelper(debug, classpathRoots))); + TestPlan testPlan = launcher.discover(request); + + testPlan.getRoots().stream() + .flatMap(rootIdentifier -> testPlan.getDescendants(rootIdentifier).stream()) + .map(TestIdentifier::getSource) + .filter(Optional::isPresent) + .map(Optional::get) + .filter(ClassSource.class::isInstance) + .map(ClassSource.class::cast) + .map(ClassSource::getJavaClass) + .forEach(this::registerTestClassForReflection); + + return testPlan; } private void registerTestClassForReflection(Class clazz) { @@ -116,11 +170,26 @@ public static void debug(String format, Object... args) { } public static boolean debug() { - if (!ImageInfo.inImageCode()) { - return debug; - } else { - return ImageSingletons.lookup(JUnitPlatformFeature.class).debug; + return ImageSingletons.lookup(JUnitPlatformFeature.class).debug; + } + + private Stream readAllFiles(Path dir, String prefix) throws IOException { + return findFiles(dir, prefix).map(outputFile -> { + try { + return Files.readAllLines(outputFile); + } catch (IOException ex) { + throw new UncheckedIOException(ex); + } + }).flatMap(List::stream); + } + + private static Stream findFiles(Path dir, String prefix) throws IOException { + if (!Files.exists(dir)) { + return Stream.empty(); } + return Files.find(dir, Integer.MAX_VALUE, + (path, basicFileAttributes) -> (basicFileAttributes.isRegularFile() + && path.getFileName().toString().startsWith(prefix))); } } diff --git a/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/NativeImageJUnitLauncher.java b/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/NativeImageJUnitLauncher.java index b7858f26b..c386fa1c5 100644 --- a/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/NativeImageJUnitLauncher.java +++ b/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/NativeImageJUnitLauncher.java @@ -43,8 +43,6 @@ import org.graalvm.nativeimage.ImageInfo; import org.graalvm.nativeimage.ImageSingletons; -import org.graalvm.nativeimage.Platform; -import org.graalvm.nativeimage.Platforms; import org.junit.platform.launcher.Launcher; import org.junit.platform.launcher.TestExecutionListener; import org.junit.platform.launcher.TestPlan; @@ -61,17 +59,11 @@ public class NativeImageJUnitLauncher { static final String DEFAULT_OUTPUT_FOLDER = Paths.get("test-results-native").resolve("test").toString(); final Launcher launcher; - TestPlan testPlan; - final TestsDiscoveryHelper testsDiscoveryHelper; + final TestPlan testPlan; - @Platforms(Platform.HOSTED_ONLY.class) - public NativeImageJUnitLauncher(TestsDiscoveryHelper testsDiscoveryHelper) { - this.testsDiscoveryHelper = testsDiscoveryHelper; - launcher = testsDiscoveryHelper.getLauncher(); - } - - private void discoverTests() { - testPlan = testsDiscoveryHelper.discoverTestPlan(); + public NativeImageJUnitLauncher(Launcher launcher, TestPlan testPlan) { + this.launcher = launcher; + this.testPlan = testPlan; } public void registerTestExecutionListeners(TestExecutionListener testExecutionListener) { @@ -123,8 +115,7 @@ public static void main(String... args) { PrintWriter out = new PrintWriter(System.out); NativeImageJUnitLauncher launcher = ImageSingletons.lookup(NativeImageJUnitLauncher.class); - //Discover the test plan at runtime. - launcher.discoverTests(); + if (!silent) { out.println("JUnit Platform on Native Image - report"); out.println("----------------------------------------\n"); diff --git a/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/TestsDiscoveryHelper.java b/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/TestsDiscoveryHelper.java deleted file mode 100644 index f0a2ca5fa..000000000 --- a/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/TestsDiscoveryHelper.java +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package org.graalvm.junit.platform; - -import org.graalvm.compiler.serviceprovider.JavaVersionUtil; -import org.junit.platform.engine.DiscoverySelector; -import org.junit.platform.engine.discovery.DiscoverySelectors; -import org.junit.platform.engine.discovery.UniqueIdSelector; -import org.junit.platform.engine.support.descriptor.ClassSource; -import org.junit.platform.launcher.Launcher; -import org.junit.platform.launcher.LauncherDiscoveryRequest; -import org.junit.platform.launcher.TestIdentifier; -import org.junit.platform.launcher.TestPlan; -import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder; -import org.junit.platform.launcher.core.LauncherFactory; -import org.junit.platform.launcher.listeners.UniqueIdTrackingListener; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -public class TestsDiscoveryHelper { - public static final String TESTDISCOVERY_OUTPUT = "testdiscovery.output"; - public static final String DEBUG = "debug"; - - private List selectors; - private Launcher launcher = LauncherFactory.create(); - private TestPlan testPlan; - - public static void main(String[] args) throws IOException { - if (args.length == 0) { - throw new RuntimeException("Must set classpath roots"); - } - List list = Arrays.stream(args[0].split(File.pathSeparator)).map(s -> Paths.get(s)).collect(Collectors.toList()); - TestsDiscoveryHelper testsDiscoveryHelper = new TestsDiscoveryHelper(Boolean.parseBoolean(System.getProperty(DEBUG, "false")), list); - List> ret = testsDiscoveryHelper.discoverTests(); - String outputPath = System.getProperty(TESTDISCOVERY_OUTPUT); - String output = ret.stream().map(c -> c.getName()).reduce((s1, s2) -> s1 + "\n" + s2).get(); - try (FileWriter fw = new FileWriter(new File(outputPath))) { - fw.write(output); - fw.flush(); - } catch (IOException e) { - throw e; - } - } - - public TestsDiscoveryHelper(boolean debug, List classpathRoots) { - selectors = getSelectors(debug, classpathRoots); - } - - public Launcher getLauncher() { - return launcher; - } - - public TestPlan discoverTestPlan() { - LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request() - .selectors(selectors) - .build(); - testPlan = launcher.discover(request); - return testPlan; - } - - /** - * Launch another Java process to discover tests to avoid unintended class initialization for native image - * building. - * @param debug is debug turned on - * @param classpathRoots class paths - * @return a list of discovered test names - */ - public static List launchTestDiscovery(boolean debug, List classpathRoots) { - int discoverResult; - Path resultFile; - try { - resultFile = Files.createTempFile("native-image-build-tool-ret-", ""); - ProcessBuilder pb = new ProcessBuilder(); - - String javaHome = System.getProperty("java.home"); - List command = new ArrayList<>(); - command.add(javaHome + File.separator + "bin" + File.separator + "java"); - StringBuilder args = new StringBuilder(" "); - String debugPort = System.getProperty("isolateTestDiscoveryDebugPort"); - if (debugPort != null && !debugPort.equals("-1")) { - args.append("-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address="); - if (JavaVersionUtil.JAVA_SPEC >= 9) { - args.append("*:"); - } - args.append(debugPort).append(" "); - } - - // Use the same system properties as current Java process - System.getProperties().forEach((k, v) -> { - if (!k.equals("line.separator") && !k.equals("java.system.class.loader") - && !((String) k).startsWith("jdk.module")) { - args.append("-D" + k + "=\"" + v + "\"").append(" "); - } - }); - args.append("-D" + TESTDISCOVERY_OUTPUT + "=" + resultFile).append(" "); - args.append("-D" + DEBUG + "=" + debug).append(" "); - args.append("-cp").append(" "); - String cp = classpathRoots.stream().map(p -> p.toString()).collect(Collectors.joining(File.pathSeparator)); - args.append(cp).append(" "); - args.append(TestsDiscoveryHelper.class.getName()).append(" "); - args.append(cp).append(" "); - - // Run the new process in the form of "java @argfile" - Path argFile = Files.createTempFile("native-image-build-tool-args-", ""); - try (FileWriter fw = new FileWriter(argFile.toFile())) { - fw.write(args.toString()); - fw.flush(); - } catch (IOException e) { - throw e; - } - command.add("@" + argFile.toString()); - pb.command(command); - Map env = pb.environment(); - if (env == null) { - env = new HashMap<>(); - } - env.putAll(System.getenv()); - - pb.inheritIO(); - System.out.println("[junit-platform-native] Launching tests discovery in a a separated JVM."); - Process process = pb.start(); - discoverResult = process.waitFor(); - } catch (IOException | InterruptedException e) { - throw new RuntimeException(e); - } - // The discovery results are written in the file, read it. - List ret; - if (discoverResult == 0) { - try { - ret = new ArrayList<>(); - BufferedReader br = new BufferedReader(new FileReader(resultFile.toFile())); - String line; - while ((line = br.readLine()) != null) { - ret.add(line); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } else { - throw new RuntimeException("Discover test plan was failed."); - } - return ret; - } - - /** - * Use the JUnit Platform Launcher to discover tests and register classes - * for reflection. - * - * @return a List of discovered junit test classes - */ - public List> discoverTests() { - discoverTestPlan(); - return testPlan.getRoots().stream() - .flatMap(rootIdentifier -> testPlan.getDescendants(rootIdentifier).stream()) - .map(TestIdentifier::getSource) - .filter(Optional::isPresent) - .map(Optional::get) - .filter(ClassSource.class::isInstance) - .map(ClassSource.class::cast) - .map(cs -> cs.getJavaClass()).collect(Collectors.toList()); - } - - private List getSelectors(boolean debug, List classpathRoots) { - try { - Path outputDir = Paths.get(System.getProperty(UniqueIdTrackingListener.OUTPUT_DIR_PROPERTY_NAME)); - String prefix = System.getProperty(UniqueIdTrackingListener.OUTPUT_FILE_PREFIX_PROPERTY_NAME, - UniqueIdTrackingListener.DEFAULT_OUTPUT_FILE_PREFIX); - List selectors = readAllFiles(outputDir, prefix) - .map(DiscoverySelectors::selectUniqueId) - .collect(Collectors.toList()); - if (!selectors.isEmpty()) { - System.out.printf( - "[junit-platform-native] Running in 'test listener' mode using files matching pattern [%s*] " - + "found in folder [%s] and its subfolders.%n", - prefix, outputDir.toAbsolutePath()); - return selectors; - } - } catch (Exception ex) { - JUnitPlatformFeature.debug("Failed to read UIDs from UniqueIdTrackingListener output files: " + ex.getMessage()); - } - - System.out.println("[junit-platform-native] Running in 'test discovery' mode. Note that this is a fallback mode."); - if (debug) { - classpathRoots.forEach(entry -> JUnitPlatformFeature.debug("Selecting classpath root: " + entry)); - } - return DiscoverySelectors.selectClasspathRoots(new HashSet<>(classpathRoots)); - } - - private Stream readAllFiles(Path dir, String prefix) throws IOException { - return findFiles(dir, prefix).map(outputFile -> { - try { - return Files.readAllLines(outputFile); - } catch (IOException ex) { - throw new UncheckedIOException(ex); - } - }).flatMap(List::stream); - } - - private static Stream findFiles(Path dir, String prefix) throws IOException { - if (!Files.exists(dir)) { - return Stream.empty(); - } - return Files.find(dir, Integer.MAX_VALUE, - (path, basicFileAttributes) -> (basicFileAttributes.isRegularFile() - && path.getFileName().toString().startsWith(prefix))); - } -} diff --git a/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/config/platform/PlatformConfigProvider.java b/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/config/platform/PlatformConfigProvider.java index a07344f1c..d67cd5d77 100644 --- a/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/config/platform/PlatformConfigProvider.java +++ b/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/config/platform/PlatformConfigProvider.java @@ -58,6 +58,7 @@ public void onLoad(NativeImageConfiguration config) { "org.junit.platform.launcher.core.LauncherConfigurationParameters", "org.junit.platform.commons.logging.LoggerFactory", "org.junit.platform.engine.UniqueIdFormat", + "org.junit.platform.commons.util.ReflectionUtils", // https://github.com/graalvm/native-build-tools/issues/300 "org.junit.platform.reporting.open.xml.OpenTestReportGeneratingListener" }; diff --git a/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/config/vintage/VintageConfigProvider.java b/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/config/vintage/VintageConfigProvider.java index c2cf51dbe..b5a6eec98 100644 --- a/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/config/vintage/VintageConfigProvider.java +++ b/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/config/vintage/VintageConfigProvider.java @@ -53,6 +53,8 @@ public void onLoad(NativeImageConfiguration config) { "org.junit.vintage.engine.support.UniqueIdReader", "org.junit.vintage.engine.support.UniqueIdStringifier", "org.junit.runner.Description", + "org.junit.runners.BlockJUnit4ClassRunner", + "org.junit.runners.JUnit4", /* Workaround until we can register serializable classes from a native-image feature */ "org.junit.runner.Result" }; diff --git a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeTestMojo.java b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeTestMojo.java index 809eebd26..aaf95fbe7 100644 --- a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeTestMojo.java +++ b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeTestMojo.java @@ -84,12 +84,6 @@ public class NativeTestMojo extends AbstractNativeImageMojo { @Parameter(property = "skipNativeTests", defaultValue = "false") private boolean skipNativeTests; - @Parameter(property = "isolateTestDiscovery", defaultValue = "true") - private boolean isolateTestDiscovery; - - @Parameter(property = "isolateTestDiscoveryDebugPort", defaultValue = "-1") - private int isolateTestDiscoveryDebugPort; - @Override protected void populateApplicationClasspath() throws MojoExecutionException { super.populateApplicationClasspath(); @@ -144,11 +138,6 @@ public void execute() throws MojoExecutionException { configureEnvironment(); buildArgs.add("--features=org.graalvm.junit.platform.JUnitPlatformFeature"); - buildArgs.add("-DisolateTestDiscovery=" + isolateTestDiscovery); - if (isolateTestDiscovery) { - buildArgs.add("-DisolateTestDiscoveryDebugPort=" + isolateTestDiscoveryDebugPort); - } - if (systemProperties == null) { systemProperties = new HashMap<>(); } From 421b6b6afd0a74805fba02c3d14b2c852ce817f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Champeau?= Date: Thu, 27 Jul 2023 15:47:29 +0200 Subject: [PATCH 11/13] Add support for PGO instrumentation (#471) * Add support for PGO instrumentation This commit adds support for PGO instrumentation. This should be enabled by adding the `--pgo-instrument` option to the Gradle command line. When this is done, then the generated binary will be compiled with PGO instrumentation enabled, and the binary name will be suffixed with `-instrumented`. It is possible to run the instrumented binary directly too, in which case the profile files will be written in the same directory as the binary. * Add support for a PGO profiles directory By convention, the directory is set to `src/pgo-profiles/`. For example, for the `main` binary, the directory where to put PGO profiles would be `src/pgo-profiles/main`. If that directory is present _and that we're not instrumenting_, then the profile will be used when compiling with native image. It is possible to provide multiple profiles in a single directory. * Remove GraalVM version from workflows * Add documentation about PGO support See #457 * Fix JUnit native test * Make checkstyle happy * Fix tests * Temporarily(?) disable testing with config cache As we're not compatible. Test `org.graalvm.buildtools.gradle.OfficialMetadataRepoFunctionalTest` throws an incomprehensible error message, in all versions of Gradle I've tested: ``` Configuration cache state could not be cached: field `spec` of `org.gradle.api.internal.tasks.execution.SelfDescribingSpec` bean found in task `:compileJava` of type `org.gradle.api.tasks.compile.JavaCompile`: error writing value of type 'org.gradle.api.internal.tasks.compile.CompilerForkUtils$$Lambda$1235/0x00000008015b1c38' > Unable to make field private final java.lang.Object[] java.lang.invoke.SerializedLambda.capturedArgs accessible: module java.base does not "opens java.lang.invoke" to unnamed module @3cc98b0c ``` This PR also rewrote some code which fixed other configuration cache issues which arose _before_ reaching this one. * Upgrade to JUnit 5.10.0 * Make checkstyle happy * Fix test * Restore configuration cache tests * Update baseline versions for config cache --- .../actions/prepare-environment/action.yml | 10 +- .github/workflows/deploy-documentation.yml | 4 +- .github/workflows/deploy-snapshots.yml | 4 +- .github/workflows/test-graalvm-metadata.yml | 4 +- .../workflows/test-junit-platform-native.yml | 4 +- .../workflows/test-native-gradle-plugin.yml | 14 +- .../workflows/test-native-maven-plugin.yml | 8 +- ...rg.graalvm.build.functional-testing.gradle | 14 +- common/junit-platform-native/build.gradle | 2 +- .../config/jupiter/JupiterConfigProvider.java | 19 +- docs/src/docs/asciidoc/gradle-plugin.adoc | 41 +++ docs/src/docs/asciidoc/index.adoc | 6 + gradle/libs.versions.toml | 4 +- gradle/wrapper/gradle-wrapper.properties | 2 +- .../DeprecatedExtensionFunctionalTest.groovy | 94 ------- .../JavaApplicationFunctionalTest.groovy | 41 +++ ...aApplicationWithAgentFunctionalTest.groovy | 2 - .../OfficialMetadataRepoFunctionalTest.groovy | 1 + .../ReachabilityMetadataFunctionalTest.groovy | 5 +- .../gradle/RequiredVersionTest.groovy | 48 ---- .../buildtools/gradle/NativeImagePlugin.java | 172 ++++++++---- .../gradle/dsl/NativeImageCompileOptions.java | 17 ++ .../internal/BaseNativeImageOptions.java | 7 + .../internal/DefaultGraalVmExtension.java | 2 - .../internal/DelegatingCompileOptions.java | 11 + .../DeprecatedNativeImageOptions.java | 257 ------------------ .../NativeImageCommandLineProvider.java | 10 + .../gradle/tasks/BuildNativeImageTask.java | 14 +- .../gradle/tasks/NativeRunTask.java | 10 +- native-maven-plugin/build.gradle.kts | 1 - .../maven/RequireVersionFunctionalTest.groovy | 66 ----- .../gradle.properties | 4 +- .../gradle.properties | 4 +- .../gradle.properties | 4 +- .../java-application-with-reflection/pom.xml | 2 +- .../gradle.properties | 4 +- .../java-application-with-resources/pom.xml | 2 +- .../gradle.properties | 4 +- samples/java-application-with-tests/pom.xml | 2 +- samples/java-application/gradle.properties | 4 +- samples/java-library/gradle.properties | 4 +- .../gradle.properties | 4 +- .../metadata-repo-integration/build.gradle | 7 +- .../gradle.properties | 4 +- samples/multi-project-with-tests/pom.xml | 2 +- .../gradle.properties | 4 +- 46 files changed, 338 insertions(+), 611 deletions(-) delete mode 100644 native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/DeprecatedExtensionFunctionalTest.groovy delete mode 100644 native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/RequiredVersionTest.groovy delete mode 100644 native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/DeprecatedNativeImageOptions.java delete mode 100644 native-maven-plugin/src/functionalTest/groovy/org/graalvm/buildtools/maven/RequireVersionFunctionalTest.groovy diff --git a/.github/actions/prepare-environment/action.yml b/.github/actions/prepare-environment/action.yml index 6f1e80333..0461ea5ca 100644 --- a/.github/actions/prepare-environment/action.yml +++ b/.github/actions/prepare-environment/action.yml @@ -6,14 +6,10 @@ inputs: description: 'secrets.GITHUB_TOKEN' required: false default: '' - graalvm-version: - description: 'GraalVM version to use' - required: false - default: 'dev' java-version: description: 'Java version to use' required: false - default: '11' + default: '17' push-access: description: 'Does this workflow require push access?' required: false @@ -26,13 +22,13 @@ inputs: runs: using: "composite" steps: - - name: "🔧 Install GraalVM ${{ inputs.graalvm-version }} (JDK${{ inputs.java-version }})" + - name: "🔧 Install GraalVM (JDK${{ inputs.java-version }})" uses: graalvm/setup-graalvm@main with: components: 'native-image' github-token: ${{ inputs.github-token }} java-version: ${{ inputs.java-version }} - version: ${{ inputs.graalvm-version }} + distribution: 'graalvm' - name: "🔒 Configure push access" if: ${{ inputs.push-access == '1' }} shell: "bash" diff --git a/.github/workflows/deploy-documentation.yml b/.github/workflows/deploy-documentation.yml index 780cf9550..50d7ee871 100644 --- a/.github/workflows/deploy-documentation.yml +++ b/.github/workflows/deploy-documentation.yml @@ -18,8 +18,7 @@ jobs: strategy: fail-fast: false matrix: - graalvm-version: [ latest ] - java-version: [ 11 ] + java-version: [ 17 ] os: [ ubuntu-20.04 ] steps: - name: "☁ Checkout repository" @@ -30,7 +29,6 @@ jobs: uses: ./.github/actions/prepare-environment with: github-token: ${{ secrets.GITHUB_TOKEN }} - graalvm-version: ${{ matrix.graalvm-version }} java-version: ${{ matrix.java-version }} push-access: 1 ssh-key: ${{ secrets.SSH_PRIVATE_KEY }} diff --git a/.github/workflows/deploy-snapshots.yml b/.github/workflows/deploy-snapshots.yml index a6a5f1638..832b4d912 100644 --- a/.github/workflows/deploy-snapshots.yml +++ b/.github/workflows/deploy-snapshots.yml @@ -20,8 +20,7 @@ jobs: strategy: fail-fast: false matrix: - graalvm-version: [ latest ] - java-version: [ 11 ] + java-version: [ 17 ] os: [ ubuntu-22.04 ] steps: - name: "☁ Checkout repository" @@ -32,7 +31,6 @@ jobs: uses: ./.github/actions/prepare-environment with: github-token: ${{ secrets.GITHUB_TOKEN }} - graalvm-version: ${{ matrix.graalvm-version }} java-version: ${{ matrix.java-version }} push-access: 1 ssh-key: ${{ secrets.SSH_PRIVATE_KEY }} diff --git a/.github/workflows/test-graalvm-metadata.yml b/.github/workflows/test-graalvm-metadata.yml index 2cf79755a..1684f7d57 100644 --- a/.github/workflows/test-graalvm-metadata.yml +++ b/.github/workflows/test-graalvm-metadata.yml @@ -24,8 +24,7 @@ jobs: strategy: fail-fast: false matrix: - graalvm-version: [ 22.3.0 ] - java-version: [ 11 ] + java-version: [ 17 ] os: [ ubuntu-20.04 ] steps: - name: "☁️ Checkout repository" @@ -33,7 +32,6 @@ jobs: - name: "🔧 Prepare environment" uses: ./.github/actions/prepare-environment with: - graalvm-version: ${{ matrix.graalvm-version }} java-version: ${{ matrix.java-version }} github-token: ${{ secrets.GITHUB_TOKEN }} - name: "❓ Checkstyle" diff --git a/.github/workflows/test-junit-platform-native.yml b/.github/workflows/test-junit-platform-native.yml index 03ba6cda1..765017d3b 100644 --- a/.github/workflows/test-junit-platform-native.yml +++ b/.github/workflows/test-junit-platform-native.yml @@ -24,8 +24,7 @@ jobs: strategy: fail-fast: false matrix: - graalvm-version: [ 22.3.0 ] - java-version: [ 11 ] + java-version: [ 17 ] os: [ ubuntu-20.04 ] steps: - name: "☁️ Checkout repository" @@ -33,7 +32,6 @@ jobs: - name: "🔧 Prepare environment" uses: ./.github/actions/prepare-environment with: - graalvm-version: ${{ matrix.graalvm-version }} java-version: ${{ matrix.java-version }} github-token: ${{ secrets.GITHUB_TOKEN }} - name: "❓ Checkstyle" diff --git a/.github/workflows/test-native-gradle-plugin.yml b/.github/workflows/test-native-gradle-plugin.yml index 6f5d15cb4..4f0191b10 100644 --- a/.github/workflows/test-native-gradle-plugin.yml +++ b/.github/workflows/test-native-gradle-plugin.yml @@ -28,8 +28,7 @@ jobs: strategy: fail-fast: false matrix: - graalvm-version: [ latest ] # dev - java-version: [ 11 ] + java-version: [ 17 ] os: [ ubuntu-20.04 ] steps: - name: "☁️ Checkout repository" @@ -37,7 +36,6 @@ jobs: - name: "🔧 Prepare environment" uses: ./.github/actions/prepare-environment with: - graalvm-version: ${{ matrix.graalvm-version }} java-version: ${{ matrix.java-version }} github-token: ${{ secrets.GITHUB_TOKEN }} - name: "❓ Unit tests and inspections" @@ -54,18 +52,16 @@ jobs: fail-fast: false matrix: gradle-version: ["current", "7.4"] - gradle-config-cache-version: ["current", "7.5.1"] + gradle-config-cache-version: ["current", "8.0.1"] # Following versions are disabled temporarily in order to speed up PR testing # "7.3.3", "7.2", "7.1", "6.8.3" - graalvm-version: [ latest ] # dev - java-version: [ 11 ] + java-version: [ 17 ] os: [ ubuntu-20.04 ] steps: - name: "☁️ Checkout repository" uses: actions/checkout@v2 - uses: ./.github/actions/prepare-environment with: - graalvm-version: ${{ matrix.graalvm-version }} java-version: ${{ matrix.java-version }} github-token: ${{ secrets.GITHUB_TOKEN }} - name: "❓ Check and test the plugin" @@ -86,15 +82,13 @@ jobs: strategy: fail-fast: false matrix: - graalvm-version: [ latest ] - java-version: [ 11 ] + java-version: [ 17 ] os: [ windows-latest ] steps: - name: "☁️ Checkout repository" uses: actions/checkout@v2 - uses: ./.github/actions/prepare-environment with: - graalvm-version: ${{ matrix.graalvm-version }} java-version: ${{ matrix.java-version }} github-token: ${{ secrets.GITHUB_TOKEN }} - name: "❓ Check and test the Gradle plugin" diff --git a/.github/workflows/test-native-maven-plugin.yml b/.github/workflows/test-native-maven-plugin.yml index afff175c8..04ab2038d 100644 --- a/.github/workflows/test-native-maven-plugin.yml +++ b/.github/workflows/test-native-maven-plugin.yml @@ -28,15 +28,13 @@ jobs: strategy: fail-fast: false matrix: - graalvm-version: [ latest ] # dev - java-version: [ 11 ] + java-version: [ 17 ] os: [ ubuntu-20.04 ] steps: - name: "☁️ Checkout repository" uses: actions/checkout@v2 - uses: ./.github/actions/prepare-environment with: - graalvm-version: ${{ matrix.graalvm-version }} java-version: ${{ matrix.java-version }} github-token: ${{ secrets.GITHUB_TOKEN }} - name: "❓ Check and test the plugin" @@ -55,15 +53,13 @@ jobs: strategy: fail-fast: false matrix: - graalvm-version: [ latest ] # dev - java-version: [ 11 ] + java-version: [ 17 ] os: [ windows-latest ] steps: - name: "☁️ Checkout repository" uses: actions/checkout@v2 - uses: ./.github/actions/prepare-environment with: - graalvm-version: ${{ matrix.graalvm-version }} java-version: ${{ matrix.java-version }} github-token: ${{ secrets.GITHUB_TOKEN }} - name: "❓ Check and test the Maven plugin" diff --git a/build-logic/gradle-functional-testing/src/main/groovy/org.graalvm.build.functional-testing.gradle b/build-logic/gradle-functional-testing/src/main/groovy/org.graalvm.build.functional-testing.gradle index 7ab742051..9cb42a434 100644 --- a/build-logic/gradle-functional-testing/src/main/groovy/org.graalvm.build.functional-testing.gradle +++ b/build-logic/gradle-functional-testing/src/main/groovy/org.graalvm.build.functional-testing.gradle @@ -75,14 +75,14 @@ gradlePlugin.testSourceSets(sourceSets.functionalTest) configurations.functionalTestImplementation.extendsFrom(configurations.testImplementation) def graalVm = javaToolchains.launcherFor { - languageVersion.set(JavaLanguageVersion.of(11)) - vendor.set(JvmVendorSpec.matching("GraalVM")) + languageVersion.set(JavaLanguageVersion.of(17)) +// vendor.set(JvmVendorSpec.matching("Oracle Corporation")) } def fullFunctionalTest = tasks.register("fullFunctionalTest") ['functionalTest', 'configCacheFunctionalTest'].each { baseName -> - ["current", "7.4", "7.6.2"].each { gradleVersion -> + ["current", "7.4", "7.6.2", "8.0.1"].each { gradleVersion -> String taskName = gradleVersion == 'current' ? baseName : "gradle${gradleVersion}${baseName.capitalize()}" // Add a task to run the functional tests def testTask = tasks.register(taskName, Test) { @@ -105,6 +105,14 @@ def fullFunctionalTest = tasks.register("fullFunctionalTest") javaLauncher.set(graalVm) if (baseName == 'configCacheFunctionalTest') { systemProperty('config.cache', 'true') + // These args are required so that we can debug tests which + // run with the configuration cache, see https://github.com/gradle/gradle/issues/25898 + jvmArgs = [ + '--add-opens=java.base/java.lang=ALL-UNNAMED', + '--add-opens=java.base/java.util=ALL-UNNAMED', + '--add-opens=java.base/java.lang.invoke=ALL-UNNAMED', + '--add-opens=java.base/java.net=ALL-UNNAMED', + ] } } fullFunctionalTest.configure { diff --git a/common/junit-platform-native/build.gradle b/common/junit-platform-native/build.gradle index 491b66850..3c47d325c 100644 --- a/common/junit-platform-native/build.gradle +++ b/common/junit-platform-native/build.gradle @@ -61,7 +61,7 @@ dependencies { apply from: "gradle/native-image-testing.gradle" -test { +tasks.named('test') { doFirst { delete { delete testIdsDir.get().asFile } } diff --git a/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/config/jupiter/JupiterConfigProvider.java b/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/config/jupiter/JupiterConfigProvider.java index 5dc6dd422..fd6e98d9a 100644 --- a/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/config/jupiter/JupiterConfigProvider.java +++ b/common/junit-platform-native/src/main/java/org/graalvm/junit/platform/config/jupiter/JupiterConfigProvider.java @@ -81,16 +81,25 @@ public void onLoad(NativeImageConfiguration config) { "org.junit.jupiter.engine.execution.ConditionEvaluator", "org.junit.jupiter.engine.execution.ExecutableInvoker", "org.junit.jupiter.params.provider.EnumSource$Mode", + // new in Junit 5.10 + "org.junit.platform.launcher.core.LauncherConfig", + "org.junit.jupiter.engine.config.InstantiatingConfigurationParameterConverter" }; for (String className : buildTimeInitializedClasses) { config.initializeAtBuildTime(className); } - try { - Class executor = Class.forName("org.junit.jupiter.engine.extension.TimeoutExtension$ExecutorResource"); - config.registerAllClassMembersForReflection(executor); - } catch (ClassNotFoundException e) { - debug("Failed to register class for reflection. Reason: %s", e); + String[] registeredForReflection = { + "org.junit.jupiter.engine.extension.TimeoutExtension$ExecutorResource", + "org.junit.jupiter.engine.extension.TimeoutInvocationFactory$SingleThreadExecutorResource" + }; + for (String className : registeredForReflection) { + try { + Class executor = Class.forName(className); + config.registerAllClassMembersForReflection(executor); + } catch (ClassNotFoundException e) { + debug("Failed to register class for reflection. Reason: %s", e); + } } } diff --git a/docs/src/docs/asciidoc/gradle-plugin.adoc b/docs/src/docs/asciidoc/gradle-plugin.adoc index 6e2f0667e..b6b5296a6 100644 --- a/docs/src/docs/asciidoc/gradle-plugin.adoc +++ b/docs/src/docs/asciidoc/gradle-plugin.adoc @@ -449,6 +449,47 @@ include::../snippets/gradle/kotlin/build.gradle.kts[tags=include-metadata] For more advanced configurations you can declare a `org.graalvm.buildtools.gradle.tasks.CollectReachabilityMetadata` task and set the appropriate properties. +[[pgo-support]] +== Profile-guided optimizations + +The plugin supports building images with https://www.graalvm.org/latest/reference-manual/native-image/guides/optimize-native-executable-with-pgo/[Profile-Guided Optimizations]. + +It works in 3 phases: + +- the first one consists in generating a binary with instrumentation enabled +- the second phase consists in running the binary in order to gather profiling information +- the third phase consists in compiling the binary with the generated profile + +In order to generate a binary with instrumentation enabled, you should run the `nativeCompile` command with the `--pgo-instrument` command line option: + +`./gradlew nativeCompile --pgo-instrument` + +This will generate a binary under `build/native/nativeCompile` with the `-instrumented` suffix. +You can run the binary to gather profiling data: + +[source,bash] +---- +$ cd build/native/nativeCompile/ +$ ./my-application-instrumented` +---- + +A `default.iprof` file will be generated once the application is stopped. +Alternatively, you can have Gradle both generate and run the instrumented binary in a single command by running: + +`./gradlew nativeCompile --pgo-instrument nativeRun` + +In which case the profile will automatically be stored into `build/native/nativeCompile`. + +The last phase consists in copying the generated profile, so that it's automatically used when building the native binary. +The conventional location for profiles is `src/pgo-profiles/`. +By default, we're using the `main` binary so the location will be `src/pgo-profiles/main`. +Copy the `default.iprof` file into that directory, then run: + +`./gradlew nativeCompile` + +The profile will automatically be used and the binary compiled with PGO. +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. + [[plugin-configurations]] == Configurations defined by the plugin diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index e05167835..996f512e1 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -19,6 +19,12 @@ If you are using alternative build systems, see < // Add DSL extensions for building and testing NativeImageOptions mainOptions = createMainOptions(graalExtension, project); - deprecateExtension(project, mainOptions, DEPRECATED_NATIVE_BUILD_EXTENSION, "main"); project.getPlugins().withId("application", p -> mainOptions.getMainClass().convention( Objects.requireNonNull(project.getExtensions().findByType(JavaApplication.class)).getMainClass() @@ -333,6 +332,15 @@ private void configureAutomaticTaskCreation(Project project, task.setDescription("Executes the " + options.getName() + " native binary"); task.getImage().convention(imageBuilder.flatMap(BuildNativeImageTask::getOutputFile)); task.getRuntimeArgs().convention(options.getRuntimeArgs()); + task.getInternalRuntimeArgs().convention( + imageBuilder.zip(options.getPgoInstrument(), serializableBiFunctionOf((builder, pgo) -> { + if (Boolean.TRUE.equals(pgo)) { + File outputDir = builder.getOutputDirectory().get().getAsFile(); + return Collections.singletonList("-XX:ProfilesDumpFile=" + new File(outputDir, "default.iprof").getAbsolutePath()); + } + return Collections.emptyList(); + }) + )); }); configureClasspathJarFor(tasks, options, imageBuilder); SourceSet sourceSet = "test".equals(binaryName) ? sourceSets.getByName(SourceSet.TEST_SOURCE_SET_NAME) : sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME); @@ -343,7 +351,7 @@ private void configureAutomaticTaskCreation(Project project, transitiveProjectArtifacts(project, sourceSet.getRuntimeClasspathConfigurationName()), deriveTaskName(binaryName, "generate", "ResourcesConfigFile")); options.getConfigurationFileDirectories().from(generateResourcesConfig.map(serializableTransformerOf(t -> - t.getOutputFile().map(f -> f.getAsFile().getParentFile()) + t.getOutputFile().map(serializableTransformerOf(f -> f.getAsFile().getParentFile())) ))); configureJvmReachabilityConfigurationDirectories(project, graalExtension, options, sourceSet); configureJvmReachabilityExcludeConfigArgs(project, graalExtension, options, sourceSet); @@ -355,48 +363,96 @@ private void configureJvmReachabilityConfigurationDirectories(Project project, NativeImageOptions options, SourceSet sourceSet) { options.getConfigurationFileDirectories().from( - graalVMReachabilityQuery(project, + graalVMReachabilityQueryForConfigDirectories(project, graalExtension, sourceSet, - configuration -> true, - this::getConfigurationDirectory, - Collectors.toList()) + configuration -> true) ); } - private File getConfigurationDirectory(ModuleVersionIdentifier moduleVersion, - DirectoryConfiguration configuration) { + private static File getConfigurationDirectory(DirectoryConfiguration configuration) { return configuration.getDirectory().toAbsolutePath().toFile(); } - private Provider graalVMReachabilityQuery(Project project, GraalVMExtension graalExtension, - SourceSet sourceSet, Predicate filter, - BiFunction mapper, - Collector collector) { + private Provider> graalVMReachabilityQueryForConfigDirectories(Project project, GraalVMExtension graalExtension, + SourceSet sourceSet, Predicate filter) { GraalVMReachabilityMetadataRepositoryExtension extension = reachabilityExtensionOn(graalExtension); Provider metadataServiceProvider = graalVMReachabilityMetadataService(project, extension); - ResolutionResult resolutionResult = project.getConfigurations() + Provider rootComponent = project.getConfigurations() .getByName(sourceSet.getRuntimeClasspathConfigurationName()) .getIncoming() - .getResolutionResult(); + .getResolutionResult() + .getRootComponent(); + SetProperty excludedModulesProperty = extension.getExcludedModules(); + MapProperty moduleToConfigVersion = extension.getModuleToConfigVersion(); + Property uri = extension.getUri(); + ProviderFactory providers = project.getProviders(); return extension.getEnabled().flatMap(serializableTransformerOf(enabled -> { - if (enabled && extension.getUri().isPresent()) { - Set excludedModules = extension.getExcludedModules().getOrElse(Collections.emptySet()); - Map forcedVersions = extension.getModuleToConfigVersion().getOrElse(Collections.emptyMap()); - return metadataServiceProvider.map(serializableTransformerOf(service -> { - Set components = resolutionResult.getAllComponents(); - Stream mapped = components.stream().flatMap(serializableFunctionOf(component -> { - ModuleVersionIdentifier moduleVersion = component.getModuleVersion(); - Set configurations = service.findConfigurationsFor(excludedModules, forcedVersions, moduleVersion); - return configurations.stream() - .filter(filter) - .map(serializableFunctionOf(configuration -> mapper.apply(moduleVersion, configuration))); + if (Boolean.TRUE.equals(enabled) && uri.isPresent()) { + Set excludedModules = excludedModulesProperty.getOrElse(Collections.emptySet()); + Map forcedVersions = moduleToConfigVersion.getOrElse(Collections.emptyMap()); + return metadataServiceProvider.map(serializableTransformerOf(service -> { + Set components = findAllComponentsFrom(rootComponent.get()); + return components.stream().flatMap(serializableFunctionOf(component -> { + ModuleVersionIdentifier moduleVersion = component.getModuleVersion(); + Set configurations = service.findConfigurationsFor(excludedModules, forcedVersions, moduleVersion); + return configurations.stream() + .filter(filter) + .map(NativeImagePlugin::getConfigurationDirectory); + })).collect(Collectors.toList()); })); - return mapped.collect(collector); - })); + } + return providers.provider(Collections::emptyList); + })); + } + + private Provider>> graalVMReachabilityQueryForExcludeList(Project project, GraalVMExtension graalExtension, + SourceSet sourceSet, Predicate filter) { + GraalVMReachabilityMetadataRepositoryExtension extension = reachabilityExtensionOn(graalExtension); + Provider metadataServiceProvider = graalVMReachabilityMetadataService(project, extension); + Provider rootComponent = project.getConfigurations() + .getByName(sourceSet.getRuntimeClasspathConfigurationName()) + .getIncoming() + .getResolutionResult() + .getRootComponent(); + SetProperty excludedModulesProperty = extension.getExcludedModules(); + MapProperty moduleToConfigVersion = extension.getModuleToConfigVersion(); + Property uri = extension.getUri(); + ProviderFactory providers = project.getProviders(); + return extension.getEnabled().flatMap(serializableTransformerOf(enabled -> { + if (Boolean.TRUE.equals(enabled) && uri.isPresent()) { + Set excludedModules = excludedModulesProperty.getOrElse(Collections.emptySet()); + Map forcedVersions = moduleToConfigVersion.getOrElse(Collections.emptyMap()); + return metadataServiceProvider.map(serializableTransformerOf(service -> { + Set components = findAllComponentsFrom(rootComponent.get()); + return components.stream().flatMap(serializableFunctionOf(component -> { + ModuleVersionIdentifier moduleVersion = component.getModuleVersion(); + Set configurations = service.findConfigurationsFor(excludedModules, forcedVersions, moduleVersion); + return configurations.stream() + .filter(filter) + .map(e -> getExclusionConfig(moduleVersion)); + })).collect(Collectors.toMap(ExcludeEntry::getGav, ExcludeEntry::getExcludes)); + })); + } + return providers.provider(Collections::emptyMap); + })); + } + + private static Set findAllComponentsFrom(ResolvedComponentResult resolvedComponentResult) { + Set all = new LinkedHashSet<>(); + findAllComponentsFrom(resolvedComponentResult, all); + return Collections.unmodifiableSet(all); + } + + private static void findAllComponentsFrom(ResolvedComponentResult resolvedComponentResult, Set all) { + if (all.add(resolvedComponentResult)) { + Set dependencies = resolvedComponentResult.getDependencies(); + for (DependencyResult dependencyResult : dependencies) { + if (dependencyResult instanceof ResolvedDependencyResult) { + findAllComponentsFrom(((ResolvedDependencyResult) dependencyResult).getSelected(), all); + } } - return project.getProviders().provider(() -> Stream.empty().collect(collector)); - })); + } } private Provider graalVMReachabilityMetadataService(Project project, @@ -451,21 +507,18 @@ static URI computeMetadataRepositoryUri(Project project, private void configureJvmReachabilityExcludeConfigArgs(Project project, GraalVMExtension graalExtension, NativeImageOptions options, SourceSet sourceSet) { options.getExcludeConfig().putAll( - graalVMReachabilityQuery(project, + graalVMReachabilityQueryForExcludeList(project, graalExtension, sourceSet, - DirectoryConfiguration::isOverride, - this::getExclusionConfig, - Collectors.>, String, List>toMap(Map.Entry::getKey, Map.Entry::getValue)) + DirectoryConfiguration::isOverride) ); GraalVMReachabilityMetadataRepositoryExtension repositoryExtension = reachabilityExtensionOn(graalExtension); graalVMReachabilityMetadataService(project, repositoryExtension); } - private Map.Entry> getExclusionConfig(ModuleVersionIdentifier moduleVersion, - DirectoryConfiguration configuration) { + private static ExcludeEntry getExclusionConfig(ModuleVersionIdentifier moduleVersion) { String gav = moduleVersion.getGroup() + ":" + moduleVersion.getName() + ":" + moduleVersion.getVersion(); - return new AbstractMap.SimpleEntry<>(gav, Arrays.asList("^/META-INF/native-image/.*")); + return new ExcludeEntry(gav, Arrays.asList("^/META-INF/native-image/.*")); } private static LogLevel determineLogLevel() { @@ -481,18 +534,6 @@ private static GraalVMReachabilityMetadataRepositoryExtension reachabilityExtens return ((ExtensionAware) graalExtension).getExtensions().getByType(GraalVMReachabilityMetadataRepositoryExtension.class); } - private void deprecateExtension(Project project, - NativeImageOptions delegate, - String name, - String substitute) { - ObjectFactory objects = project.getObjects(); - project.getExtensions().add(name, objects.newInstance(DeprecatedNativeImageOptions.class, - name, - delegate, - substitute, - project.getLogger())); - } - private void configureClasspathJarFor(TaskContainer tasks, NativeImageOptions options, TaskProvider imageBuilder) { String baseName = imageBuilder.getName(); TaskProvider classpathJar = tasks.register(baseName + "ClasspathJar", Jar.class, jar -> { @@ -589,9 +630,6 @@ public void registerTestBinary(Project project, // Add DSL extension for testing NativeImageOptions testOptions = createTestOptions(graalExtension, name, project, mainOptions, config.getSourceSet()); - if (isPrimaryTest) { - deprecateExtension(project, testOptions, DEPRECATED_NATIVE_TEST_EXTENSION, "test"); - } TaskProvider testTask = config.validate().getTestTask(); testTask.configure(test -> { @@ -874,4 +912,22 @@ public Iterable asArguments() { return Collections.singleton("-D" + JUNIT_PLATFORM_LISTENERS_UID_TRACKING_OUTPUT_DIR + "=" + getDirectory().getAsFile().get().getAbsolutePath()); } } + + private static final class ExcludeEntry { + private final String gav; + private final List excludes; + + private ExcludeEntry(String gav, List excludes) { + this.gav = gav; + this.excludes = excludes; + } + + public String getGav() { + return gav; + } + + public List getExcludes() { + return excludes; + } + } } diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/NativeImageCompileOptions.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/NativeImageCompileOptions.java index c0833c08e..abbaa93bf 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/NativeImageCompileOptions.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/NativeImageCompileOptions.java @@ -42,14 +42,18 @@ import org.graalvm.buildtools.gradle.dsl.agent.DeprecatedAgentOptions; import org.gradle.api.file.ConfigurableFileCollection; +import org.gradle.api.file.DirectoryProperty; import org.gradle.api.provider.ListProperty; import org.gradle.api.provider.MapProperty; import org.gradle.api.provider.Property; import org.gradle.api.tasks.Classpath; import org.gradle.api.tasks.Input; +import org.gradle.api.tasks.InputDirectory; import org.gradle.api.tasks.InputFiles; import org.gradle.api.tasks.Nested; import org.gradle.api.tasks.Optional; +import org.gradle.api.tasks.PathSensitive; +import org.gradle.api.tasks.PathSensitivity; import org.gradle.jvm.toolchain.JavaLauncher; import java.util.List; @@ -215,4 +219,17 @@ public interface NativeImageCompileOptions { @Nested DeprecatedAgentOptions getAgent(); + + /** + * When set to true, the compiled binaries will be generated with PGO instrumentation + * support. + * @return the PGO instrumentation flag + */ + @Input + Property getPgoInstrument(); + + @InputDirectory + @PathSensitive(PathSensitivity.NONE) + @Optional + DirectoryProperty getPgoProfilesDirectory(); } diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/BaseNativeImageOptions.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/BaseNativeImageOptions.java index ba2cf0edb..3832d4953 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/BaseNativeImageOptions.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/BaseNativeImageOptions.java @@ -47,6 +47,8 @@ import org.graalvm.buildtools.utils.SharedConstants; import org.gradle.api.Action; import org.gradle.api.file.ConfigurableFileCollection; +import org.gradle.api.file.DirectoryProperty; +import org.gradle.api.file.ProjectLayout; import org.gradle.api.logging.Logging; import org.gradle.api.model.ObjectFactory; import org.gradle.api.provider.ListProperty; @@ -243,6 +245,7 @@ public void resources(Action spec) { @Inject public BaseNativeImageOptions(String name, + ProjectLayout layout, ObjectFactory objectFactory, ProviderFactory providers, JavaToolchainService toolchains, @@ -263,6 +266,10 @@ public BaseNativeImageOptions(String name, getSharedLibrary().convention(false); getImageName().convention(defaultImageName); getUseFatJar().convention(false); + getPgoInstrument().convention(false); + DirectoryProperty pgoProfileDir = objectFactory.directoryProperty(); + pgoProfileDir.convention(layout.getProjectDirectory().dir("src/pgo-profiles/" + name)); + getPgoProfilesDirectory().convention(pgoProfileDir.map(d -> d.getAsFile().exists() ? d : null)); } private static Provider property(ProviderFactory providers, String name) { diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/DefaultGraalVmExtension.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/DefaultGraalVmExtension.java index e4ca369d6..1d4235f6c 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/DefaultGraalVmExtension.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/DefaultGraalVmExtension.java @@ -53,7 +53,6 @@ import org.gradle.jvm.toolchain.JavaLanguageVersion; import org.gradle.jvm.toolchain.JavaLauncher; import org.gradle.jvm.toolchain.JavaToolchainService; -import org.gradle.jvm.toolchain.JvmVendorSpec; import javax.inject.Inject; import java.util.Arrays; @@ -97,7 +96,6 @@ private void configureToolchain() { if (toolchainService != null) { return toolchainService.launcherFor(spec -> { spec.getLanguageVersion().set(JavaLanguageVersion.of(JavaVersion.current().getMajorVersion())); - spec.getVendor().set(JvmVendorSpec.matching("GraalVM")); }); } } diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/DelegatingCompileOptions.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/DelegatingCompileOptions.java index 9843ed707..c49755846 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/DelegatingCompileOptions.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/DelegatingCompileOptions.java @@ -44,6 +44,7 @@ import org.graalvm.buildtools.gradle.dsl.NativeResourcesOptions; import org.graalvm.buildtools.gradle.dsl.agent.DeprecatedAgentOptions; import org.gradle.api.file.ConfigurableFileCollection; +import org.gradle.api.file.DirectoryProperty; import org.gradle.api.provider.ListProperty; import org.gradle.api.provider.MapProperty; import org.gradle.api.provider.Property; @@ -160,4 +161,14 @@ public Property getUseFatJar() { public DeprecatedAgentOptions getAgent() { return options.getAgent(); } + + @Override + public Property getPgoInstrument() { + return options.getPgoInstrument(); + } + + @Override + public DirectoryProperty getPgoProfilesDirectory() { + return options.getPgoProfilesDirectory(); + } } diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/DeprecatedNativeImageOptions.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/DeprecatedNativeImageOptions.java deleted file mode 100644 index aeb7623e9..000000000 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/DeprecatedNativeImageOptions.java +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright (c) 2020, 2021 Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package org.graalvm.buildtools.gradle.internal; - -import org.graalvm.buildtools.gradle.dsl.NativeImageOptions; -import org.graalvm.buildtools.gradle.dsl.NativeResourcesOptions; -import org.graalvm.buildtools.gradle.dsl.agent.DeprecatedAgentOptions; -import org.gradle.api.Action; -import org.gradle.api.file.ConfigurableFileCollection; -import org.gradle.api.provider.ListProperty; -import org.gradle.api.provider.MapProperty; -import org.gradle.api.provider.Property; -import org.gradle.api.tasks.Classpath; -import org.gradle.api.tasks.Input; -import org.gradle.api.tasks.InputFiles; -import org.gradle.api.tasks.Internal; -import org.gradle.api.tasks.Nested; -import org.gradle.api.tasks.Optional; -import org.gradle.jvm.toolchain.JavaLauncher; -import org.slf4j.Logger; - -import javax.inject.Inject; -import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Supplier; - -@SuppressWarnings("DeprecatedIsStillUsed") -@Deprecated -public abstract class DeprecatedNativeImageOptions implements NativeImageOptions { - private final String name; - private final NativeImageOptions delegate; - private final String replacedWith; - private final Logger logger; - private final AtomicBoolean warned = new AtomicBoolean(); - - @Inject - public DeprecatedNativeImageOptions(String name, - NativeImageOptions delegate, - String replacedWith, - Logger logger) { - this.name = name; - this.delegate = delegate; - this.replacedWith = replacedWith; - this.logger = logger; - } - - private T warnAboutDeprecation(Supplier action) { - issueWarning(); - return action.get(); - } - - private void warnAboutDeprecation(Runnable action) { - issueWarning(); - action.run(); - } - - private void issueWarning() { - if (warned.compareAndSet(false, true)) { - logger.warn("The " + name + " extension is deprecated and will be removed. Please use the 'graalvmNative.binaries." + replacedWith + "' extension to configure the native image instead."); - } - } - - @Override - @Internal - public String getName() { - return warnAboutDeprecation(delegate::getName); - } - - @Override - @Input - public Property getImageName() { - return warnAboutDeprecation(delegate::getImageName); - } - - @Override - @Optional - @Input - public Property getMainClass() { - return warnAboutDeprecation(delegate::getMainClass); - } - - @Override - @Input - public ListProperty getBuildArgs() { - return warnAboutDeprecation(delegate::getBuildArgs); - } - - @Override - @Input - public MapProperty getSystemProperties() { - return warnAboutDeprecation(delegate::getSystemProperties); - } - - @Override - public MapProperty getEnvironmentVariables() { - return warnAboutDeprecation(delegate::getEnvironmentVariables); - } - - @Override - @Classpath - @InputFiles - public ConfigurableFileCollection getClasspath() { - return warnAboutDeprecation(delegate::getClasspath); - } - - @Override - @Input - public ListProperty getJvmArgs() { - return warnAboutDeprecation(delegate::getJvmArgs); - } - - @Override - @Input - public ListProperty getRuntimeArgs() { - return warnAboutDeprecation(delegate::getRuntimeArgs); - } - - @Override - @Input - public Property getDebug() { - return warnAboutDeprecation(delegate::getDebug); - } - - @Override - @Input - public Property getFallback() { - return warnAboutDeprecation(delegate::getFallback); - } - - @Override - @Input - public Property getVerbose() { - return warnAboutDeprecation(delegate::getVerbose); - } - - @Override - @Input - public Property getSharedLibrary() { - return warnAboutDeprecation(delegate::getSharedLibrary); - } - - @Override - @Nested - public Property getJavaLauncher() { - return warnAboutDeprecation(delegate::getJavaLauncher); - } - - @Override - @InputFiles - public ConfigurableFileCollection getConfigurationFileDirectories() { - return warnAboutDeprecation(delegate::getConfigurationFileDirectories); - } - - @Override - @Nested - public NativeResourcesOptions getResources() { - return warnAboutDeprecation(delegate::getResources); - } - - @Override - public void resources(Action spec) { - warnAboutDeprecation(() -> delegate.resources(spec)); - } - - @Override - public NativeImageOptions buildArgs(Object... buildArgs) { - return warnAboutDeprecation(() -> delegate.buildArgs(buildArgs)); - } - - @Override - public NativeImageOptions buildArgs(Iterable buildArgs) { - return warnAboutDeprecation(() -> delegate.buildArgs(buildArgs)); - } - - @Override - public NativeImageOptions systemProperties(Map properties) { - return warnAboutDeprecation(() -> delegate.systemProperties(properties)); - } - - @Override - public NativeImageOptions systemProperty(String name, Object value) { - return warnAboutDeprecation(() -> delegate.systemProperty(name, value)); - } - - @Override - public NativeImageOptions classpath(Object... paths) { - return warnAboutDeprecation(() -> delegate.classpath(paths)); - } - - @Override - public NativeImageOptions jvmArgs(Object... arguments) { - return warnAboutDeprecation(() -> delegate.jvmArgs(arguments)); - } - - @Override - public NativeImageOptions jvmArgs(Iterable arguments) { - return warnAboutDeprecation(() -> delegate.jvmArgs(arguments)); - } - - @Override - public NativeImageOptions runtimeArgs(Object... arguments) { - return warnAboutDeprecation(() -> delegate.runtimeArgs(arguments)); - } - - @Override - public NativeImageOptions runtimeArgs(Iterable arguments) { - return warnAboutDeprecation(() -> delegate.runtimeArgs(arguments)); - } - - @Override - public DeprecatedAgentOptions getAgent() { - return warnAboutDeprecation(delegate::getAgent); - } - - @Override - public void agent(Action spec) { - warnAboutDeprecation(() -> delegate.agent(spec)); - } -} diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/NativeImageCommandLineProvider.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/NativeImageCommandLineProvider.java index d30e96ca0..ceee78caa 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/NativeImageCommandLineProvider.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/NativeImageCommandLineProvider.java @@ -45,6 +45,7 @@ import org.graalvm.buildtools.utils.NativeImageUtils; import org.gradle.api.Transformer; import org.gradle.api.file.FileSystemLocation; +import org.gradle.api.file.FileTree; import org.gradle.api.file.RegularFile; import org.gradle.api.provider.Provider; import org.gradle.api.tasks.Input; @@ -58,6 +59,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Set; import java.util.stream.Collectors; public class NativeImageCommandLineProvider implements CommandLineArgumentProvider { @@ -118,6 +120,7 @@ public List asArguments() { appendBooleanOption(cliArgs, options.getSharedLibrary(), "--shared"); appendBooleanOption(cliArgs, options.getQuickBuild(), "-Ob"); appendBooleanOption(cliArgs, options.getRichOutput(), "-H:+BuildOutputColorful"); + appendBooleanOption(cliArgs, options.getPgoInstrument(), "--pgo-instrument"); if (getOutputDirectory().isPresent()) { cliArgs.add("-H:Path=" + getOutputDirectory().get()); @@ -145,6 +148,13 @@ public List asArguments() { if (options.getMainClass().isPresent()) { cliArgs.add("-H:Class=" + options.getMainClass().get()); } + if (Boolean.FALSE.equals(options.getPgoInstrument().get()) && options.getPgoProfilesDirectory().isPresent()) { + FileTree files = options.getPgoProfilesDirectory().get().getAsFileTree(); + Set profiles = files.filter(f -> f.getName().endsWith(".iprof")).getFiles(); + for (File profile : profiles) { + cliArgs.add("--pgo=" + profile); + } + } cliArgs.addAll(options.getBuildArgs().get()); if (useArgFile.getOrElse(true)) { Path argFileDir = Paths.get(workingDirectory.get()); diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/tasks/BuildNativeImageTask.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/tasks/BuildNativeImageTask.java index 71192f4c2..e96ce7d2d 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/tasks/BuildNativeImageTask.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/tasks/BuildNativeImageTask.java @@ -77,6 +77,7 @@ import java.nio.charset.StandardCharsets; import java.util.List; +import static org.graalvm.buildtools.gradle.internal.ConfigurationCacheSupport.serializableBiFunctionOf; import static org.graalvm.buildtools.gradle.internal.NativeImageExecutableLocator.graalvmHomeProvider; import static org.graalvm.buildtools.utils.SharedConstants.EXECUTABLE_EXTENSION; @@ -107,6 +108,11 @@ public void overrideDebugBuild() { getOptions().get().getDebug().set(true); } + @Option(option = "pgo-instrument", description = "Enables PGO instrumentation") + public void overridePgoInstrument() { + getOptions().get().getPgoInstrument().set(true); + } + @Inject protected abstract ExecOperations getExecOperations(); @@ -128,17 +134,19 @@ protected Provider getGraalVMHome() { @Internal public Provider getExecutableShortName() { - return getOptions().flatMap(NativeImageOptions::getImageName); + return getOptions().flatMap(options -> + options.getImageName().zip(options.getPgoInstrument(), serializableBiFunctionOf((name, pgo) -> name + (Boolean.TRUE.equals(pgo) ? "-instrumented" : ""))) + ); } @Internal public Provider getExecutableName() { - return getOptions().flatMap(options -> options.getImageName().map(name -> name + EXECUTABLE_EXTENSION)); + return getExecutableShortName().map(name -> name + EXECUTABLE_EXTENSION); } @Internal public Provider getOutputFile() { - return getOutputDirectory().map(dir -> dir.file(getExecutableName()).get()); + return getOutputDirectory().zip(getExecutableName(), Directory::file); } @Input diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/tasks/NativeRunTask.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/tasks/NativeRunTask.java index be71af965..07e474a53 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/tasks/NativeRunTask.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/tasks/NativeRunTask.java @@ -53,6 +53,8 @@ import org.gradle.process.ExecOperations; import javax.inject.Inject; +import java.util.ArrayList; +import java.util.List; import java.util.Map; @SuppressWarnings("unused") @@ -69,11 +71,13 @@ public abstract class NativeRunTask extends DefaultTask { @Optional public abstract MapProperty getEnvironment(); + @Input + public abstract ListProperty getInternalRuntimeArgs(); + @Inject protected abstract ExecOperations getExecOperations(); public NativeRunTask() { - setDescription("Runs this project as a native-image application"); setGroup(ApplicationPlugin.APPLICATION_GROUP); } @@ -82,7 +86,9 @@ public NativeRunTask() { public void exec() { getExecOperations().exec(spec -> { spec.setExecutable(getImage().get().getAsFile().getAbsolutePath()); - spec.args(getRuntimeArgs().get()); + List allRuntimeArgs = new ArrayList<>(getInternalRuntimeArgs().get()); + allRuntimeArgs.addAll(getRuntimeArgs().get()); + spec.args(allRuntimeArgs); if (getEnvironment().isPresent()) { Map env = getEnvironment().get(); for (Map.Entry entry : env.entrySet()) { diff --git a/native-maven-plugin/build.gradle.kts b/native-maven-plugin/build.gradle.kts index 42c0d5857..e87139d99 100644 --- a/native-maven-plugin/build.gradle.kts +++ b/native-maven-plugin/build.gradle.kts @@ -154,7 +154,6 @@ val prepareMavenLocalRepo = tasks.register("prepareMavenLocalRepo") { val launcher = javaToolchains.launcherFor { languageVersion.set(JavaLanguageVersion.of(11)) - vendor.set(JvmVendorSpec.matching("GraalVM")) } tasks { diff --git a/native-maven-plugin/src/functionalTest/groovy/org/graalvm/buildtools/maven/RequireVersionFunctionalTest.groovy b/native-maven-plugin/src/functionalTest/groovy/org/graalvm/buildtools/maven/RequireVersionFunctionalTest.groovy deleted file mode 100644 index 142edb4cc..000000000 --- a/native-maven-plugin/src/functionalTest/groovy/org/graalvm/buildtools/maven/RequireVersionFunctionalTest.groovy +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * The Universal Permissive License (UPL), Version 1.0 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.graalvm.buildtools.maven - -class RequireVersionFunctionalTest extends AbstractGraalVMMavenFunctionalTest { - - def "can build a native image with a valid required version"() { - withSample("java-application") - - when: - mvn '-Pnative', '-DskipTests', 'native:compile' - - then: - buildSucceeded - } - - def "can't build a native image with an invalid required version"() { - withSample("java-application") - - when: - mvn '-Pnative', '-DskipTests', '-DrequiredVersion=100', 'native:compile' - - then: - buildFailed - } - -} diff --git a/samples/java-application-with-custom-tests/gradle.properties b/samples/java-application-with-custom-tests/gradle.properties index 6e3a33b8e..87ab5df33 100644 --- a/samples/java-application-with-custom-tests/gradle.properties +++ b/samples/java-application-with-custom-tests/gradle.properties @@ -1,3 +1,3 @@ native.gradle.plugin.version = 0.9.24-SNAPSHOT -junit.jupiter.version = 5.8.1 -junit.platform.version = 1.8.1 +junit.jupiter.version = 5.10.0 +junit.platform.version = 1.9.3 diff --git a/samples/java-application-with-extra-sourceset/gradle.properties b/samples/java-application-with-extra-sourceset/gradle.properties index 6e3a33b8e..87ab5df33 100644 --- a/samples/java-application-with-extra-sourceset/gradle.properties +++ b/samples/java-application-with-extra-sourceset/gradle.properties @@ -1,3 +1,3 @@ native.gradle.plugin.version = 0.9.24-SNAPSHOT -junit.jupiter.version = 5.8.1 -junit.platform.version = 1.8.1 +junit.jupiter.version = 5.10.0 +junit.platform.version = 1.9.3 diff --git a/samples/java-application-with-reflection/gradle.properties b/samples/java-application-with-reflection/gradle.properties index 6e3a33b8e..87ab5df33 100644 --- a/samples/java-application-with-reflection/gradle.properties +++ b/samples/java-application-with-reflection/gradle.properties @@ -1,3 +1,3 @@ native.gradle.plugin.version = 0.9.24-SNAPSHOT -junit.jupiter.version = 5.8.1 -junit.platform.version = 1.8.1 +junit.jupiter.version = 5.10.0 +junit.platform.version = 1.9.3 diff --git a/samples/java-application-with-reflection/pom.xml b/samples/java-application-with-reflection/pom.xml index c6478c491..7234abc93 100644 --- a/samples/java-application-with-reflection/pom.xml +++ b/samples/java-application-with-reflection/pom.xml @@ -51,7 +51,7 @@ 1.8 UTF-8 - 5.8.1 + 5.10.0 0.9.24-SNAPSHOT 0.9.24-SNAPSHOT example-app diff --git a/samples/java-application-with-resources/gradle.properties b/samples/java-application-with-resources/gradle.properties index 6e3a33b8e..87ab5df33 100644 --- a/samples/java-application-with-resources/gradle.properties +++ b/samples/java-application-with-resources/gradle.properties @@ -1,3 +1,3 @@ native.gradle.plugin.version = 0.9.24-SNAPSHOT -junit.jupiter.version = 5.8.1 -junit.platform.version = 1.8.1 +junit.jupiter.version = 5.10.0 +junit.platform.version = 1.9.3 diff --git a/samples/java-application-with-resources/pom.xml b/samples/java-application-with-resources/pom.xml index 3ae5e1c09..7eb420b54 100644 --- a/samples/java-application-with-resources/pom.xml +++ b/samples/java-application-with-resources/pom.xml @@ -52,7 +52,7 @@ 1.8 UTF-8 0.9.24-SNAPSHOT - 5.8.1 + 5.10.0 0.9.24-SNAPSHOT example-app org.graalvm.demo.Application diff --git a/samples/java-application-with-tests/gradle.properties b/samples/java-application-with-tests/gradle.properties index 6e3a33b8e..87ab5df33 100644 --- a/samples/java-application-with-tests/gradle.properties +++ b/samples/java-application-with-tests/gradle.properties @@ -1,3 +1,3 @@ native.gradle.plugin.version = 0.9.24-SNAPSHOT -junit.jupiter.version = 5.8.1 -junit.platform.version = 1.8.1 +junit.jupiter.version = 5.10.0 +junit.platform.version = 1.9.3 diff --git a/samples/java-application-with-tests/pom.xml b/samples/java-application-with-tests/pom.xml index de13703cf..240b8400a 100644 --- a/samples/java-application-with-tests/pom.xml +++ b/samples/java-application-with-tests/pom.xml @@ -51,7 +51,7 @@ 1.8 UTF-8 - 5.8.1 + 5.10.0 0.9.24-SNAPSHOT 0.9.24-SNAPSHOT example-app diff --git a/samples/java-application/gradle.properties b/samples/java-application/gradle.properties index 6e3a33b8e..87ab5df33 100644 --- a/samples/java-application/gradle.properties +++ b/samples/java-application/gradle.properties @@ -1,3 +1,3 @@ native.gradle.plugin.version = 0.9.24-SNAPSHOT -junit.jupiter.version = 5.8.1 -junit.platform.version = 1.8.1 +junit.jupiter.version = 5.10.0 +junit.platform.version = 1.9.3 diff --git a/samples/java-library/gradle.properties b/samples/java-library/gradle.properties index 6e3a33b8e..87ab5df33 100644 --- a/samples/java-library/gradle.properties +++ b/samples/java-library/gradle.properties @@ -1,3 +1,3 @@ native.gradle.plugin.version = 0.9.24-SNAPSHOT -junit.jupiter.version = 5.8.1 -junit.platform.version = 1.8.1 +junit.jupiter.version = 5.10.0 +junit.platform.version = 1.9.3 diff --git a/samples/kotlin-application-with-tests/gradle.properties b/samples/kotlin-application-with-tests/gradle.properties index 6e3a33b8e..87ab5df33 100644 --- a/samples/kotlin-application-with-tests/gradle.properties +++ b/samples/kotlin-application-with-tests/gradle.properties @@ -1,3 +1,3 @@ native.gradle.plugin.version = 0.9.24-SNAPSHOT -junit.jupiter.version = 5.8.1 -junit.platform.version = 1.8.1 +junit.jupiter.version = 5.10.0 +junit.platform.version = 1.9.3 diff --git a/samples/metadata-repo-integration/build.gradle b/samples/metadata-repo-integration/build.gradle index 9dc689676..863a42bc8 100644 --- a/samples/metadata-repo-integration/build.gradle +++ b/samples/metadata-repo-integration/build.gradle @@ -73,8 +73,7 @@ graalvmNative { metadataRepository { enabled = true } -} - -tasks.named("jar") { - from collectReachabilityMetadata + binaries.all { + verbose = true + } } diff --git a/samples/multi-project-with-tests/gradle.properties b/samples/multi-project-with-tests/gradle.properties index 6e3a33b8e..87ab5df33 100644 --- a/samples/multi-project-with-tests/gradle.properties +++ b/samples/multi-project-with-tests/gradle.properties @@ -1,3 +1,3 @@ native.gradle.plugin.version = 0.9.24-SNAPSHOT -junit.jupiter.version = 5.8.1 -junit.platform.version = 1.8.1 +junit.jupiter.version = 5.10.0 +junit.platform.version = 1.9.3 diff --git a/samples/multi-project-with-tests/pom.xml b/samples/multi-project-with-tests/pom.xml index 5082338f7..f7319d6e6 100644 --- a/samples/multi-project-with-tests/pom.xml +++ b/samples/multi-project-with-tests/pom.xml @@ -57,7 +57,7 @@ 1.8 UTF-8 - 5.8.1 + 5.10.0 0.9.24-SNAPSHOT 0.9.24-SNAPSHOT example-app diff --git a/samples/native-config-integration/gradle.properties b/samples/native-config-integration/gradle.properties index 6e3a33b8e..87ab5df33 100644 --- a/samples/native-config-integration/gradle.properties +++ b/samples/native-config-integration/gradle.properties @@ -1,3 +1,3 @@ native.gradle.plugin.version = 0.9.24-SNAPSHOT -junit.jupiter.version = 5.8.1 -junit.platform.version = 1.8.1 +junit.jupiter.version = 5.10.0 +junit.platform.version = 1.9.3 From e7d0f9441085487fdd092bec9f88f3cda22e1f19 Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Mon, 31 Jul 2023 16:46:29 +0200 Subject: [PATCH 12/13] Bump metadata version --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 520bc19f1..b5a0e1eba 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,7 +1,7 @@ [versions] # Project versions nativeBuildTools = "0.9.24-SNAPSHOT" -metadataRepository = "0.3.2" +metadataRepository = "0.3.3" # External dependencies spock = "2.1-groovy-3.0" From 654fcd4998748357c518c564516fd8166223b292 Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Mon, 31 Jul 2023 16:39:02 +0200 Subject: [PATCH 13/13] Bump repo version to 0.9.24 and update samples --- gradle/libs.versions.toml | 2 +- native-maven-plugin/reproducers/issue-144/pom.xml | 4 ++-- samples/java-application-with-custom-packaging/pom.xml | 2 +- samples/java-application-with-custom-tests/gradle.properties | 2 +- .../java-application-with-extra-sourceset/gradle.properties | 2 +- samples/java-application-with-reflection/gradle.properties | 2 +- samples/java-application-with-reflection/pom.xml | 4 ++-- samples/java-application-with-resources/gradle.properties | 2 +- samples/java-application-with-resources/pom.xml | 4 ++-- samples/java-application-with-tests/gradle.properties | 2 +- samples/java-application-with-tests/pom.xml | 4 ++-- samples/java-application/gradle.properties | 2 +- samples/java-application/pom.xml | 4 ++-- samples/java-library/gradle.properties | 2 +- samples/java-library/pom.xml | 4 ++-- samples/kotlin-application-with-tests/gradle.properties | 2 +- samples/metadata-repo-integration/gradle.properties | 2 +- samples/metadata-repo-integration/pom.xml | 4 ++-- samples/multi-project-with-tests/gradle.properties | 2 +- samples/multi-project-with-tests/pom.xml | 4 ++-- samples/native-config-integration/gradle.properties | 2 +- samples/native-config-integration/pom.xml | 4 ++-- 22 files changed, 31 insertions(+), 31 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b5a0e1eba..7a023e1ae 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] # Project versions -nativeBuildTools = "0.9.24-SNAPSHOT" +nativeBuildTools = "0.9.24" metadataRepository = "0.3.3" # External dependencies diff --git a/native-maven-plugin/reproducers/issue-144/pom.xml b/native-maven-plugin/reproducers/issue-144/pom.xml index 9b2340e03..aa78da37c 100644 --- a/native-maven-plugin/reproducers/issue-144/pom.xml +++ b/native-maven-plugin/reproducers/issue-144/pom.xml @@ -56,8 +56,8 @@ 1.8 UTF-8 - 0.9.24-SNAPSHOT - 0.9.24-SNAPSHOT + 0.9.24 + 0.9.24 example-app org.graalvm.demo.Application diff --git a/samples/java-application-with-custom-packaging/pom.xml b/samples/java-application-with-custom-packaging/pom.xml index aca9f52b8..3299736fd 100644 --- a/samples/java-application-with-custom-packaging/pom.xml +++ b/samples/java-application-with-custom-packaging/pom.xml @@ -61,7 +61,7 @@ 3.3.4 org.graalvm.demo.Application netty - 0.9.24-SNAPSHOT + 0.9.24 diff --git a/samples/java-application-with-custom-tests/gradle.properties b/samples/java-application-with-custom-tests/gradle.properties index 87ab5df33..b98e9df66 100644 --- a/samples/java-application-with-custom-tests/gradle.properties +++ b/samples/java-application-with-custom-tests/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.24-SNAPSHOT +native.gradle.plugin.version = 0.9.24 junit.jupiter.version = 5.10.0 junit.platform.version = 1.9.3 diff --git a/samples/java-application-with-extra-sourceset/gradle.properties b/samples/java-application-with-extra-sourceset/gradle.properties index 87ab5df33..b98e9df66 100644 --- a/samples/java-application-with-extra-sourceset/gradle.properties +++ b/samples/java-application-with-extra-sourceset/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.24-SNAPSHOT +native.gradle.plugin.version = 0.9.24 junit.jupiter.version = 5.10.0 junit.platform.version = 1.9.3 diff --git a/samples/java-application-with-reflection/gradle.properties b/samples/java-application-with-reflection/gradle.properties index 87ab5df33..b98e9df66 100644 --- a/samples/java-application-with-reflection/gradle.properties +++ b/samples/java-application-with-reflection/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.24-SNAPSHOT +native.gradle.plugin.version = 0.9.24 junit.jupiter.version = 5.10.0 junit.platform.version = 1.9.3 diff --git a/samples/java-application-with-reflection/pom.xml b/samples/java-application-with-reflection/pom.xml index 7234abc93..658e24c27 100644 --- a/samples/java-application-with-reflection/pom.xml +++ b/samples/java-application-with-reflection/pom.xml @@ -52,8 +52,8 @@ 1.8 UTF-8 5.10.0 - 0.9.24-SNAPSHOT - 0.9.24-SNAPSHOT + 0.9.24 + 0.9.24 example-app org.graalvm.demo.Application diff --git a/samples/java-application-with-resources/gradle.properties b/samples/java-application-with-resources/gradle.properties index 87ab5df33..b98e9df66 100644 --- a/samples/java-application-with-resources/gradle.properties +++ b/samples/java-application-with-resources/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.24-SNAPSHOT +native.gradle.plugin.version = 0.9.24 junit.jupiter.version = 5.10.0 junit.platform.version = 1.9.3 diff --git a/samples/java-application-with-resources/pom.xml b/samples/java-application-with-resources/pom.xml index 7eb420b54..d57638863 100644 --- a/samples/java-application-with-resources/pom.xml +++ b/samples/java-application-with-resources/pom.xml @@ -51,9 +51,9 @@ 1.8 UTF-8 - 0.9.24-SNAPSHOT + 0.9.24 5.10.0 - 0.9.24-SNAPSHOT + 0.9.24 example-app org.graalvm.demo.Application diff --git a/samples/java-application-with-tests/gradle.properties b/samples/java-application-with-tests/gradle.properties index 87ab5df33..b98e9df66 100644 --- a/samples/java-application-with-tests/gradle.properties +++ b/samples/java-application-with-tests/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.24-SNAPSHOT +native.gradle.plugin.version = 0.9.24 junit.jupiter.version = 5.10.0 junit.platform.version = 1.9.3 diff --git a/samples/java-application-with-tests/pom.xml b/samples/java-application-with-tests/pom.xml index 240b8400a..97ec5c08f 100644 --- a/samples/java-application-with-tests/pom.xml +++ b/samples/java-application-with-tests/pom.xml @@ -52,8 +52,8 @@ 1.8 UTF-8 5.10.0 - 0.9.24-SNAPSHOT - 0.9.24-SNAPSHOT + 0.9.24 + 0.9.24 example-app org.graalvm.demo.Application diff --git a/samples/java-application/gradle.properties b/samples/java-application/gradle.properties index 87ab5df33..b98e9df66 100644 --- a/samples/java-application/gradle.properties +++ b/samples/java-application/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.24-SNAPSHOT +native.gradle.plugin.version = 0.9.24 junit.jupiter.version = 5.10.0 junit.platform.version = 1.9.3 diff --git a/samples/java-application/pom.xml b/samples/java-application/pom.xml index 6033d683d..1326f98cb 100644 --- a/samples/java-application/pom.xml +++ b/samples/java-application/pom.xml @@ -51,8 +51,8 @@ 1.8 UTF-8 - 0.9.24-SNAPSHOT - 0.9.24-SNAPSHOT + 0.9.24 + 0.9.24 example-app org.graalvm.demo.Application diff --git a/samples/java-library/gradle.properties b/samples/java-library/gradle.properties index 87ab5df33..b98e9df66 100644 --- a/samples/java-library/gradle.properties +++ b/samples/java-library/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.24-SNAPSHOT +native.gradle.plugin.version = 0.9.24 junit.jupiter.version = 5.10.0 junit.platform.version = 1.9.3 diff --git a/samples/java-library/pom.xml b/samples/java-library/pom.xml index 821b58544..136e39728 100644 --- a/samples/java-library/pom.xml +++ b/samples/java-library/pom.xml @@ -51,8 +51,8 @@ 1.8 UTF-8 - 0.9.24-SNAPSHOT - 0.9.24-SNAPSHOT + 0.9.24 + 0.9.24 java-library diff --git a/samples/kotlin-application-with-tests/gradle.properties b/samples/kotlin-application-with-tests/gradle.properties index 87ab5df33..b98e9df66 100644 --- a/samples/kotlin-application-with-tests/gradle.properties +++ b/samples/kotlin-application-with-tests/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.24-SNAPSHOT +native.gradle.plugin.version = 0.9.24 junit.jupiter.version = 5.10.0 junit.platform.version = 1.9.3 diff --git a/samples/metadata-repo-integration/gradle.properties b/samples/metadata-repo-integration/gradle.properties index dda35760e..7fea870d1 100644 --- a/samples/metadata-repo-integration/gradle.properties +++ b/samples/metadata-repo-integration/gradle.properties @@ -1,4 +1,4 @@ -native.gradle.plugin.version = 0.9.24-SNAPSHOT +native.gradle.plugin.version = 0.9.24 h2.version = 2.1.210 netty.version = 4.1.80.Final logback.version = 1.4.4 diff --git a/samples/metadata-repo-integration/pom.xml b/samples/metadata-repo-integration/pom.xml index 766e2ce1c..16a209a39 100644 --- a/samples/metadata-repo-integration/pom.xml +++ b/samples/metadata-repo-integration/pom.xml @@ -51,8 +51,8 @@ 1.8 UTF-8 - 0.9.24-SNAPSHOT - 0.9.24-SNAPSHOT + 0.9.24 + 0.9.24 2.1.210 4.1.80.Final 1.4.4 diff --git a/samples/multi-project-with-tests/gradle.properties b/samples/multi-project-with-tests/gradle.properties index 87ab5df33..b98e9df66 100644 --- a/samples/multi-project-with-tests/gradle.properties +++ b/samples/multi-project-with-tests/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.24-SNAPSHOT +native.gradle.plugin.version = 0.9.24 junit.jupiter.version = 5.10.0 junit.platform.version = 1.9.3 diff --git a/samples/multi-project-with-tests/pom.xml b/samples/multi-project-with-tests/pom.xml index f7319d6e6..966e5bc27 100644 --- a/samples/multi-project-with-tests/pom.xml +++ b/samples/multi-project-with-tests/pom.xml @@ -58,8 +58,8 @@ 1.8 UTF-8 5.10.0 - 0.9.24-SNAPSHOT - 0.9.24-SNAPSHOT + 0.9.24 + 0.9.24 example-app org.graalvm.demo.Application diff --git a/samples/native-config-integration/gradle.properties b/samples/native-config-integration/gradle.properties index 87ab5df33..b98e9df66 100644 --- a/samples/native-config-integration/gradle.properties +++ b/samples/native-config-integration/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.24-SNAPSHOT +native.gradle.plugin.version = 0.9.24 junit.jupiter.version = 5.10.0 junit.platform.version = 1.9.3 diff --git a/samples/native-config-integration/pom.xml b/samples/native-config-integration/pom.xml index 0b77d453b..89f5cfcba 100644 --- a/samples/native-config-integration/pom.xml +++ b/samples/native-config-integration/pom.xml @@ -51,8 +51,8 @@ 1.8 UTF-8 - 0.9.24-SNAPSHOT - 0.9.24-SNAPSHOT + 0.9.24 + 0.9.24 example-app org.graalvm.example.Application