diff --git a/.github/workflows/deploy-documentation.yml b/.github/workflows/deploy-documentation.yml index 88519ab65..780cf9550 100644 --- a/.github/workflows/deploy-documentation.yml +++ b/.github/workflows/deploy-documentation.yml @@ -18,7 +18,7 @@ jobs: strategy: fail-fast: false matrix: - graalvm-version: [ dev ] + graalvm-version: [ latest ] java-version: [ 11 ] os: [ ubuntu-20.04 ] steps: diff --git a/.github/workflows/deploy-snapshots.yml b/.github/workflows/deploy-snapshots.yml index cd460ed8f..b3f6f7707 100644 --- a/.github/workflows/deploy-snapshots.yml +++ b/.github/workflows/deploy-snapshots.yml @@ -20,9 +20,9 @@ jobs: strategy: fail-fast: false matrix: - graalvm-version: [ dev ] + graalvm-version: [ latest ] java-version: [ 11 ] - os: [ ubuntu-20.04 ] + os: [ ubuntu-22.04 ] steps: - name: "☁ Checkout repository" uses: actions/checkout@v2 diff --git a/.github/workflows/test-native-gradle-plugin.yml b/.github/workflows/test-native-gradle-plugin.yml index 2e6ceefdc..e2ddc2116 100644 --- a/.github/workflows/test-native-gradle-plugin.yml +++ b/.github/workflows/test-native-gradle-plugin.yml @@ -28,7 +28,7 @@ jobs: strategy: fail-fast: false matrix: - graalvm-version: [ dev ] + graalvm-version: [ latest ] # dev java-version: [ 11 ] os: [ ubuntu-20.04 ] steps: @@ -53,8 +53,10 @@ jobs: strategy: fail-fast: false matrix: - gradle-version: ["current", "7.3.3", "7.2", "7.1", "6.8.3", "6.7.1"] - graalvm-version: [ dev ] + gradle-version: ["current", "6.7.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 ] os: [ ubuntu-20.04 ] steps: @@ -81,7 +83,7 @@ jobs: strategy: fail-fast: false matrix: - graalvm-version: [ dev ] + graalvm-version: [ latest ] java-version: [ 11 ] os: [ windows-latest ] steps: diff --git a/.github/workflows/test-native-maven-plugin.yml b/.github/workflows/test-native-maven-plugin.yml index 4d9c96548..afff175c8 100644 --- a/.github/workflows/test-native-maven-plugin.yml +++ b/.github/workflows/test-native-maven-plugin.yml @@ -28,7 +28,7 @@ jobs: strategy: fail-fast: false matrix: - graalvm-version: [ dev ] + graalvm-version: [ latest ] # dev java-version: [ 11 ] os: [ ubuntu-20.04 ] steps: @@ -55,7 +55,7 @@ jobs: strategy: fail-fast: false matrix: - graalvm-version: [ dev ] + graalvm-version: [ latest ] # dev java-version: [ 11 ] os: [ windows-latest ] steps: diff --git a/build-logic/aggregator/build.gradle.kts b/build-logic/aggregator/build.gradle.kts index 17086414b..e1fc239a9 100644 --- a/build-logic/aggregator/build.gradle.kts +++ b/build-logic/aggregator/build.gradle.kts @@ -47,8 +47,3 @@ repositories { mavenCentral() gradlePluginPortal() } - -dependencies { - implementation(libs.jgit) - implementation(libs.jsch) -} diff --git a/build-logic/aggregator/src/main/kotlin/org.graalvm.build.aggregator.gradle.kts b/build-logic/aggregator/src/main/kotlin/org.graalvm.build.aggregator.gradle.kts index a2a46b559..c28db8655 100644 --- a/build-logic/aggregator/src/main/kotlin/org.graalvm.build.aggregator.gradle.kts +++ b/build-logic/aggregator/src/main/kotlin/org.graalvm.build.aggregator.gradle.kts @@ -3,6 +3,7 @@ import org.gradle.api.publish.plugins.PublishingPlugin import org.gradle.api.tasks.Delete import org.gradle.api.tasks.bundling.Zip import org.gradle.kotlin.dsl.* +import java.nio.file.Files.createTempDirectory /* * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. @@ -124,7 +125,7 @@ val updateSamples by tasks.registering mapOf( "updateSamplesDir" to "samples", "updateMavenReprosDir" to "native-maven-plugin/reproducers" -).forEach { taskName, dir -> +).forEach { (taskName, dir) -> val t = tasks.register(taskName) { inputDirectory.set(layout.projectDirectory.dir(dir)) versions.put("native.gradle.plugin.version", nativeBuildToolsVersion) @@ -138,37 +139,46 @@ mapOf( } } +val snapshotDir: File = createTempDirectory("snapshot-repo").toFile() +// val snapshotDir: File = snapshotsRepo.get().asFile.toPath().resolve("native-build-tools").toFile() +// Having nested git directories tend to break for me, so for now we'll use temp directory every time. val cloneSnapshots = tasks.register("cloneSnapshotRepository") { repositoryUri.set("git@github.com:graalvm/native-build-tools.git") -// repositoryUri.set(file(".").absolutePath) - repositoryDirectory.set(layout.buildDirectory.dir("snapshots")) + repositoryDirectory.set(snapshotDir) branch.set("snapshots") } val prepareRepository = tasks.register("resetHead") { dependsOn(cloneSnapshots) - repositoryDirectory.set(layout.buildDirectory.dir("snapshots")) - mode.set(org.eclipse.jgit.api.ResetCommand.ResetType.HARD) + repositoryDirectory.set(snapshotDir) + mode.set("hard") ref.set("25ecdec020f57dbe980eeb052c71659ccd0d9bcc") } -val addSnapshots = tasks.register("addSnapshots") { +val copySnapshots = tasks.register("copySnapshots") { dependsOn(prepareRepository) - repositoryDirectory.set(layout.buildDirectory.dir("snapshots")) - pattern.set("org/") + from(snapshotsRepo.get().asFile.toPath()) + into(snapshotDir) + include("org/**") +} + +val addSnapshots = tasks.register("addSnapshots") { + dependsOn(copySnapshots) + repositoryDirectory.set(snapshotDir) + pattern.set("*") } val commitSnapshots = tasks.register("commitSnapshots") { dependsOn(addSnapshots) - repositoryDirectory.set(layout.buildDirectory.dir("snapshots")) + repositoryDirectory.set(snapshotDir) message.set("Publishing new snapshot") amend.set(false) } val pushSnapshots = tasks.register("pushSnapshots") { dependsOn(commitSnapshots) - repositoryDirectory.set(layout.buildDirectory.dir("snapshots")) + repositoryDirectory.set(snapshotDir) force.set(true) } diff --git a/build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/AbstractGitTask.kt b/build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/AbstractGitTask.kt index 40f9308b2..7cb92abab 100644 --- a/build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/AbstractGitTask.kt +++ b/build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/AbstractGitTask.kt @@ -41,36 +41,47 @@ package org.graalvm.build.tasks -import com.jcraft.jsch.JSch -import org.eclipse.jgit.transport.SshSessionFactory -import org.eclipse.jgit.transport.JschConfigSessionFactory -import org.eclipse.jgit.transport.OpenSshConfig - -import com.jcraft.jsch.Session -import org.eclipse.jgit.util.FS - +import org.gradle.api.Action import org.gradle.api.DefaultTask import org.gradle.api.file.DirectoryProperty import org.gradle.api.tasks.InputDirectory -import org.gradle.api.tasks.Internal +import org.gradle.kotlin.dsl.setEnvironment +import org.gradle.process.ExecOperations +import org.gradle.process.ExecSpec +import javax.inject.Inject abstract class AbstractGitTask : DefaultTask() { - @get:Internal - val sshSessionFactory: SshSessionFactory = object : JschConfigSessionFactory() { - override fun configure(host: OpenSshConfig.Host, session: Session) { - session.setConfig("StrictHostKeyChecking", "no") - session.setConfig("PreferredAuthentications", "publickey") - session.setConfig("IdentitiesOnly", "yes") + + @get:InputDirectory + abstract val repositoryDirectory: DirectoryProperty + + @get:Inject + abstract val execOperations: ExecOperations + + protected fun runGit(vararg args: String) { + runGit(args.asList()) + } + + protected fun runGit(args: List) { + val command = ArrayList() + command.add(0, "git") + command.addAll(args) + println("Running git with `${command.joinToString(separator=" ")}`") + + val result = execOperations.exec { + commandLine(command) + val newEnvironment = java.util.HashMap(environment) + newEnvironment["GIT_SSH_COMMAND"] = "ssh " + + "-o StrictHostKeyChecking=no " + + "-o PreferredAuthentications=publickey " + + "-o IdentitiesOnly=yes" + environment = newEnvironment + setWorkingDir(repositoryDirectory.asFile) } - override fun createDefaultJSch(fs: FS?): JSch { - return super.createDefaultJSch(fs).also { - val identityFile = System.getProperty("user.home") + "/.ssh/id_rsa" - it.addIdentity(identityFile) - } + val retCode = result.exitValue + if (retCode != 0) { + throw RuntimeException("Git process exited with return code $retCode") } } - - @get:InputDirectory - abstract val repositoryDirectory: DirectoryProperty } diff --git a/build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/GitAdd.kt b/build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/GitAdd.kt index f6dd0ec84..9ad10cbae 100644 --- a/build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/GitAdd.kt +++ b/build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/GitAdd.kt @@ -41,7 +41,6 @@ package org.graalvm.build.tasks -import org.eclipse.jgit.api.Git import org.gradle.api.provider.Property import org.gradle.api.tasks.Input import org.gradle.api.tasks.TaskAction @@ -52,8 +51,6 @@ abstract class GitAdd : AbstractGitTask() { @TaskAction fun execute() { - Git.open(repositoryDirectory.asFile.get()).use { - it.add().addFilepattern(pattern.get()).call() - } + runGit("add", pattern.get()) } } diff --git a/build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/GitClone.kt b/build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/GitClone.kt index 6d0616da0..cdea27d8d 100644 --- a/build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/GitClone.kt +++ b/build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/GitClone.kt @@ -41,9 +41,6 @@ package org.graalvm.build.tasks -import org.eclipse.jgit.api.Git -import org.eclipse.jgit.transport.SshTransport -import org.eclipse.jgit.util.FileUtils import org.gradle.api.file.DirectoryProperty import org.gradle.api.provider.Property import org.gradle.api.tasks.Input @@ -52,7 +49,7 @@ import org.gradle.api.tasks.TaskAction abstract class GitClone : AbstractGitTask() { @get:OutputDirectory - override abstract val repositoryDirectory: DirectoryProperty + abstract override val repositoryDirectory: DirectoryProperty @get:Input abstract val repositoryUri: Property @@ -63,23 +60,16 @@ abstract class GitClone : AbstractGitTask() { @TaskAction fun execute() { val repoDir = repositoryDirectory.asFile.get() - if (repoDir.exists()) { + while (repoDir.exists()) { + // TODO: There seems to be a task ordering / race condition issue here since `deleteRecursively` fails + // several times in a row. println("Deleting $repoDir") - FileUtils.delete(repoDir, FileUtils.RECURSIVE) + repoDir.deleteRecursively() } repoDir.mkdirs() val repo = repositoryUri.get() val branch = this.branch.get() println("Cloning $repo branch '$branch' into '${repoDir}'...") - Git.cloneRepository() - .setURI(repo) - .setBranch(branch) - .setDirectory(repoDir) - .setTransportConfigCallback { transport -> - val sshTransport: SshTransport = transport as SshTransport - sshTransport.sshSessionFactory = sshSessionFactory - } - .call() - .close() + runGit("clone", "--branch", branch, repo, ".") } } diff --git a/build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/GitCommit.kt b/build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/GitCommit.kt index 776cf7f6b..63cce4811 100644 --- a/build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/GitCommit.kt +++ b/build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/GitCommit.kt @@ -41,7 +41,6 @@ package org.graalvm.build.tasks -import org.eclipse.jgit.api.Git import org.gradle.api.provider.Property import org.gradle.api.tasks.Input import org.gradle.api.tasks.TaskAction @@ -55,13 +54,10 @@ abstract class GitCommit : AbstractGitTask() { @TaskAction fun execute() { - Git.open(repositoryDirectory.asFile.get()).use { - it.commit() - .setAll(true) - .setMessage(message.get()) - .setAmend(amend.get()) - .setSign(false) - .call() + val cmd = arrayListOf("commit", "-a", "-m", message.get()) + if (amend.get()) { + cmd.add("--amend") } + runGit(cmd) } } diff --git a/build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/GitPush.kt b/build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/GitPush.kt index d57630eac..32e812e6f 100644 --- a/build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/GitPush.kt +++ b/build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/GitPush.kt @@ -41,8 +41,6 @@ package org.graalvm.build.tasks -import org.eclipse.jgit.api.Git -import org.eclipse.jgit.transport.SshTransport import org.gradle.api.provider.Property import org.gradle.api.tasks.Input import org.gradle.api.tasks.TaskAction @@ -53,14 +51,11 @@ abstract class GitPush : AbstractGitTask() { @TaskAction fun execute() { - Git.open(repositoryDirectory.asFile.get()).use { - it.push() - .setTransportConfigCallback { transport -> - val sshTransport: SshTransport = transport as SshTransport - sshTransport.sshSessionFactory = sshSessionFactory - } - .setForce(force.get()) - .call() + val cmd = arrayListOf("push") + if (force.get()) { + cmd.add("-f") } + println("Pushing to remote Git repository") + runGit(cmd) } } diff --git a/build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/GitReset.kt b/build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/GitReset.kt index 0dd59a3e6..ceef3999e 100644 --- a/build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/GitReset.kt +++ b/build-logic/aggregator/src/main/kotlin/org/graalvm/build/tasks/GitReset.kt @@ -41,8 +41,6 @@ package org.graalvm.build.tasks -import org.eclipse.jgit.api.Git -import org.eclipse.jgit.api.ResetCommand import org.gradle.api.provider.Property import org.gradle.api.tasks.Input import org.gradle.api.tasks.TaskAction @@ -52,15 +50,16 @@ abstract class GitReset : AbstractGitTask() { abstract val ref: Property @get:Input - abstract val mode: Property + abstract val mode: Property + @TaskAction fun execute() { - Git.open(repositoryDirectory.asFile.get()).use { - it.reset() - .setRef(ref.get()) - .setMode(mode.get()) - .call() + val cmd = arrayListOf("reset") + if (mode.isPresent) { + cmd.add("--${mode.get().toLowerCase()}") } + cmd.add(ref.get()) + runGit(cmd) } } diff --git a/build-logic/common-plugins/src/main/kotlin/org.graalvm.build.publishing.gradle.kts b/build-logic/common-plugins/src/main/kotlin/org.graalvm.build.publishing.gradle.kts index 02b63bd4c..182d16891 100644 --- a/build-logic/common-plugins/src/main/kotlin/org.graalvm.build.publishing.gradle.kts +++ b/build-logic/common-plugins/src/main/kotlin/org.graalvm.build.publishing.gradle.kts @@ -153,6 +153,6 @@ plugins.withId("java-test-fixtures") { // Get a handle on the software component factory interface Services { - @javax.inject.Inject + @Inject fun getSoftwareComponentFactory(): SoftwareComponentFactory } diff --git a/common/graalvm-reachability-metadata/src/main/java/org/graalvm/reachability/DirectoryConfiguration.java b/common/graalvm-reachability-metadata/src/main/java/org/graalvm/reachability/DirectoryConfiguration.java new file mode 100644 index 000000000..db3f824f0 --- /dev/null +++ b/common/graalvm-reachability-metadata/src/main/java/org/graalvm/reachability/DirectoryConfiguration.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2020, 2022 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.reachability; + +import java.nio.file.Path; + +public class DirectoryConfiguration { + + private final Path directory; + + private final boolean override; + + public DirectoryConfiguration(Path directory, boolean override) { + this.directory = directory; + this.override = override; + } + + public Path getDirectory() { + return directory; + } + + public boolean isOverride() { + return override; + } +} diff --git a/common/graalvm-reachability-metadata/src/main/java/org/graalvm/reachability/GraalVMReachabilityMetadataRepository.java b/common/graalvm-reachability-metadata/src/main/java/org/graalvm/reachability/GraalVMReachabilityMetadataRepository.java index 74a2432b0..692a2a2c8 100644 --- a/common/graalvm-reachability-metadata/src/main/java/org/graalvm/reachability/GraalVMReachabilityMetadataRepository.java +++ b/common/graalvm-reachability-metadata/src/main/java/org/graalvm/reachability/GraalVMReachabilityMetadataRepository.java @@ -40,7 +40,6 @@ */ package org.graalvm.reachability; -import java.nio.file.Path; import java.util.Collection; import java.util.Set; import java.util.function.Consumer; @@ -63,9 +62,9 @@ public interface GraalVMReachabilityMetadataRepository { * example if a configuration directory isn't available for a * particular artifact version. * @param queryBuilder the query builder - * @return the set of configuration directories matching the query + * @return the set of configuration matching the query */ - Set findConfigurationDirectoriesFor(Consumer queryBuilder); + Set findConfigurationsFor(Consumer queryBuilder); /** * Returns a list of configuration directories for the specified artifact. @@ -73,19 +72,19 @@ public interface GraalVMReachabilityMetadataRepository { * but the list may also be empty if the repository doesn't contain any. * Never null. * @param gavCoordinates the artifact GAV coordinates (group:artifact:version) - * @return a list of configuration directories + * @return a list of configuration */ - default Set findConfigurationDirectoriesFor(String gavCoordinates) { - return findConfigurationDirectoriesFor(q -> q.forArtifacts(gavCoordinates)); + default Set findConfigurationsFor(String gavCoordinates) { + return findConfigurationsFor(q -> q.forArtifacts(gavCoordinates)); } /** * Returns the set of configuration directories for all the modules supplied * as an argument. * @param modules the list of modules - * @return the set of configuration directories + * @return the set of configuration */ - default Set findConfigurationDirectoriesFor(Collection modules) { - return findConfigurationDirectoriesFor(q -> q.forArtifacts(modules)); + default Set findConfigurationsFor(Collection modules) { + return findConfigurationsFor(q -> q.forArtifacts(modules)); } } diff --git a/common/graalvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/FileSystemRepository.java b/common/graalvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/FileSystemRepository.java index 76dc0e26f..51b04d051 100644 --- a/common/graalvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/FileSystemRepository.java +++ b/common/graalvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/FileSystemRepository.java @@ -40,6 +40,7 @@ */ package org.graalvm.reachability.internal; +import org.graalvm.reachability.DirectoryConfiguration; import org.graalvm.reachability.GraalVMReachabilityMetadataRepository; import org.graalvm.reachability.Query; import org.graalvm.reachability.internal.index.artifacts.SingleModuleJsonVersionToConfigDirectoryIndex; @@ -90,7 +91,7 @@ public static boolean isSupportedArchiveFormat(String path) { } @Override - public Set findConfigurationDirectoriesFor(Consumer queryBuilder) { + public Set findConfigurationsFor(Consumer queryBuilder) { DefaultQuery query = new DefaultQuery(); queryBuilder.accept(query); return query.getArtifacts() @@ -106,25 +107,25 @@ public Set findConfigurationDirectoriesFor(Consumer queryBu if (artifactQuery.getForcedConfig().isPresent()) { String configVersion = artifactQuery.getForcedConfig().get(); logger.log(groupId, artifactId, version, "Configuration is forced to version " + configVersion); - return index.findForcedConfiguration(configVersion); + return index.findConfiguration(groupId, artifactId, configVersion); } - Optional configurationDirectory = index.findConfigurationDirectory(groupId, artifactId, version); - if (!configurationDirectory.isPresent() && artifactQuery.isUseLatestVersion()) { + Optional configuration = index.findConfiguration(groupId, artifactId, version); + if (!configuration.isPresent() && artifactQuery.isUseLatestVersion()) { logger.log(groupId, artifactId, version, "Configuration directory not found. Trying latest version."); - configurationDirectory = index.findLatestConfigurationFor(groupId, artifactId); - if (!configurationDirectory.isPresent()) { + configuration = index.findLatestConfigurationFor(groupId, artifactId); + if (!configuration.isPresent()) { logger.log(groupId, artifactId, version, "Latest version not found!"); } } - Optional finalConfigurationDirectory = configurationDirectory; + Optional finalConfigurationDirectory = configuration; logger.log(groupId, artifactId, version, () -> { if (finalConfigurationDirectory.isPresent()) { - Path path = finalConfigurationDirectory.get(); + Path path = finalConfigurationDirectory.get().getDirectory(); return "Configuration directory is " + rootDirectory.relativize(path); } return "missing."; }); - return configurationDirectory; + return configuration; }) .filter(Optional::isPresent) .map(Optional::get); diff --git a/common/graalvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/artifacts/Artifact.java b/common/graalvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/artifacts/Artifact.java index 3641a67a7..248f11f9e 100644 --- a/common/graalvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/artifacts/Artifact.java +++ b/common/graalvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/artifacts/Artifact.java @@ -52,16 +52,19 @@ public class Artifact { private final Set versions; private final String directory; private final boolean latest; + private final boolean override; @JsonCreator public Artifact(@JsonProperty("module") String module, @JsonProperty("tested-versions") Set versions, @JsonProperty("metadata-version") String directory, - @JsonProperty(value = "latest", defaultValue = "false") boolean latest) { + @JsonProperty(value = "latest", defaultValue = "false") boolean latest, + @JsonProperty(value = "override", defaultValue = "false") boolean override) { this.module = module; this.versions = versions; this.directory = directory; this.latest = latest; + this.override = override; } public String getModule() { @@ -79,4 +82,8 @@ public String getDirectory() { public boolean isLatest() { return latest; } + + public boolean isOverride() { + return override; + } } diff --git a/common/graalvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndex.java b/common/graalvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndex.java index 25709d50c..5a27bd3d9 100644 --- a/common/graalvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndex.java +++ b/common/graalvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndex.java @@ -42,6 +42,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.type.TypeFactory; +import org.graalvm.reachability.DirectoryConfiguration; import org.graalvm.reachability.internal.UncheckedIOException; import java.io.BufferedReader; @@ -80,12 +81,6 @@ private Map> parseIndexFile(Path rootPath) { } - @Override - public Optional findForcedConfiguration(String version) { - Path configDir = moduleRoot.resolve(version); - return Files.isDirectory(configDir) ? Optional.of(configDir) : Optional.empty(); - } - /** * Returns the configuration directory for the requested artifact. * @@ -95,7 +90,7 @@ public Optional findForcedConfiguration(String version) { * @return a configuration directory, or empty if no configuration directory is available */ @Override - public Optional findConfigurationDirectory(String groupId, String artifactId, String version) { + public Optional findConfiguration(String groupId, String artifactId, String version) { return findConfigurationFor(groupId, artifactId, artifact -> artifact.getVersions().contains(version)); } @@ -107,11 +102,11 @@ public Optional findConfigurationDirectory(String groupId, String artifact * @return a configuration directory, or empty if no configuration directory is available */ @Override - public Optional findLatestConfigurationFor(String groupId, String artifactId) { + public Optional findLatestConfigurationFor(String groupId, String artifactId) { return findConfigurationFor(groupId, artifactId, Artifact::isLatest); } - private Optional findConfigurationFor(String groupId, String artifactId, Predicate predicate) { + private Optional findConfigurationFor(String groupId, String artifactId, Predicate predicate) { String module = groupId + ":" + artifactId; List artifacts = index.get(module); if (artifacts == null) { @@ -121,6 +116,7 @@ private Optional findConfigurationFor(String groupId, String artifactId, P .filter(artifact -> artifact.getModule().equals(module)) .filter(predicate) .findFirst() - .map(artifact -> moduleRoot.resolve(artifact.getDirectory())); + .map(artifact -> new DirectoryConfiguration(moduleRoot.resolve(artifact.getDirectory()), artifact.isOverride())); } + } diff --git a/common/graalvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/artifacts/VersionToConfigDirectoryIndex.java b/common/graalvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/artifacts/VersionToConfigDirectoryIndex.java index 3a712265d..c93512d1e 100644 --- a/common/graalvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/artifacts/VersionToConfigDirectoryIndex.java +++ b/common/graalvm-reachability-metadata/src/main/java/org/graalvm/reachability/internal/index/artifacts/VersionToConfigDirectoryIndex.java @@ -40,33 +40,26 @@ */ package org.graalvm.reachability.internal.index.artifacts; -import java.nio.file.Path; import java.util.Optional; -public interface VersionToConfigDirectoryIndex { +import org.graalvm.reachability.DirectoryConfiguration; - /** - * Returns the specified configuration directory version, ignoring - * any existing configuration. - * @param version the requested version - * @return the configuration directory - */ - Optional findForcedConfiguration(String version); +public interface VersionToConfigDirectoryIndex { /** - * Returns the configuration directory for the requested artifact. + * Returns the configuration for the requested artifact. * @param groupId the group ID of the artifact * @param artifactId the artifact ID of the artifact * @param version the version of the artifact - * @return a configuration directory, or empty if no configuration directory is available + * @return a configuration, or empty if no configuration directory is available */ - Optional findConfigurationDirectory(String groupId, String artifactId, String version); + Optional findConfiguration(String groupId, String artifactId, String version); /** - * Returns the latest configuration directory for the requested artifact. + * Returns the latest configuration for the requested artifact. * @param groupId the group ID of the artifact * @param artifactId the artifact ID of the artifact - * @return a configuration directory, or empty if no configuration directory is available + * @return a configuration, or empty if no configuration directory is available */ - Optional findLatestConfigurationFor(String groupId, String artifactId); + Optional findLatestConfigurationFor(String groupId, String artifactId); } diff --git a/common/graalvm-reachability-metadata/src/test/java/org/graalvm/reachability/internal/FileSystemRepositoryTest.java b/common/graalvm-reachability-metadata/src/test/java/org/graalvm/reachability/internal/FileSystemRepositoryTest.java index 65c663116..b9206c89a 100644 --- a/common/graalvm-reachability-metadata/src/test/java/org/graalvm/reachability/internal/FileSystemRepositoryTest.java +++ b/common/graalvm-reachability-metadata/src/test/java/org/graalvm/reachability/internal/FileSystemRepositoryTest.java @@ -41,6 +41,7 @@ package org.graalvm.reachability.internal; +import org.graalvm.reachability.DirectoryConfiguration; import org.graalvm.reachability.Query; import org.junit.jupiter.api.Test; @@ -51,6 +52,8 @@ import java.util.function.Consumer; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; class FileSystemRepositoryTest { private FileSystemRepository repository; @@ -65,9 +68,11 @@ void testRepo1() { // then: result.hasSinglePath("org/foo/1.0"); + result.hasNoOverride(); // when: lookup("org:foo:1.1"); + result.hasOverride(); // then: result.hasSinglePath("org/foo/1.1"); @@ -87,6 +92,7 @@ void testRepo2() { // then: result.hasSinglePath("org/foo/1.1"); + result.hasNoOverride(); } @Test @@ -166,11 +172,11 @@ void canUseLatestConfigDir() { } private void lookup(Consumer builder) { - result = new Result(repository.findConfigurationDirectoriesFor(builder), repoPath); + result = new Result(repository.findConfigurationsFor(builder), repoPath); } private void lookup(String gav) { - result = new Result(repository.findConfigurationDirectoriesFor(gav), repoPath); + result = new Result(repository.findConfigurationsFor(gav), repoPath); } private void withRepo(String id) { @@ -184,20 +190,32 @@ private void withRepo(String id) { private static final class Result { private final Path repoPath; - private final Set configDirs; + private final Set configs; - private Result(Set configDirs, Path repoPath) { - this.configDirs = configDirs; + private Result(Set configs, Path repoPath) { + this.configs = configs; this.repoPath = repoPath; } public void isEmpty() { - assertEquals(0, configDirs.size()); + assertEquals(0, configs.size()); } public void hasSinglePath(String path) { - assertEquals(1, configDirs.size()); - assertEquals(repoPath.resolve(path), configDirs.iterator().next()); + assertEquals(1, configs.size()); + assertEquals(repoPath.resolve(path), configs.iterator().next().getDirectory()); + } + + public void hasOverride() { + for (DirectoryConfiguration config : configs) { + assertTrue(config.isOverride()); + } + } + + public void hasNoOverride() { + for (DirectoryConfiguration config : configs) { + assertFalse(config.isOverride()); + } } } } diff --git a/common/graalvm-reachability-metadata/src/test/java/org/graalvm/reachability/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndexTest.java b/common/graalvm-reachability-metadata/src/test/java/org/graalvm/reachability/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndexTest.java index 4cf3384e3..9198f5c33 100644 --- a/common/graalvm-reachability-metadata/src/test/java/org/graalvm/reachability/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndexTest.java +++ b/common/graalvm-reachability-metadata/src/test/java/org/graalvm/reachability/internal/index/artifacts/SingleModuleJsonVersionToConfigDirectoryIndexTest.java @@ -41,6 +41,7 @@ package org.graalvm.reachability.internal.index.artifacts; +import org.graalvm.reachability.DirectoryConfiguration; import org.junit.jupiter.api.Test; import java.io.File; @@ -61,31 +62,36 @@ class SingleModuleJsonVersionToConfigDirectoryIndexTest { void checkIndex() throws URISyntaxException { withIndex("artifact-1"); - Optional configDir = index.findConfigurationDirectory("com.foo", "bar", "1.0"); - assertTrue(configDir.isPresent()); - assertEquals(repoPath.resolve("1.0"), configDir.get()); + Optional config = index.findConfiguration("com.foo", "bar", "1.0"); + assertTrue(config.isPresent()); + assertEquals(repoPath.resolve("1.0"), config.get().getDirectory()); + assertFalse(config.get().isOverride()); - configDir = index.findConfigurationDirectory("com.foo", "bar", "1.3"); - assertTrue(configDir.isPresent()); - assertEquals(repoPath.resolve("1.0"), configDir.get()); + config = index.findConfiguration("com.foo", "bar", "1.3"); + assertTrue(config.isPresent()); + assertEquals(repoPath.resolve("1.0"), config.get().getDirectory()); + assertFalse(config.get().isOverride()); - configDir = index.findConfigurationDirectory("com.foo", "bar", "2.0"); - assertTrue(configDir.isPresent()); - assertEquals(repoPath.resolve("2.0"), configDir.get()); + config = index.findConfiguration("com.foo", "bar", "2.0"); + assertTrue(config.isPresent()); + assertEquals(repoPath.resolve("2.0"), config.get().getDirectory()); + assertTrue(config.get().isOverride()); - configDir = index.findConfigurationDirectory("com.foo", "bar", "2.5"); - assertFalse(configDir.isPresent()); + config = index.findConfiguration("com.foo", "bar", "2.5"); + assertFalse(config.isPresent()); - configDir = index.findConfigurationDirectory("com.foo", "bar-all", "2.0"); - assertTrue(configDir.isPresent()); - assertEquals(repoPath.resolve("2.0"), configDir.get()); + config = index.findConfiguration("com.foo", "bar-all", "2.0"); + assertTrue(config.isPresent()); + assertEquals(repoPath.resolve("2.0"), config.get().getDirectory()); + assertFalse(config.get().isOverride()); - configDir = index.findConfigurationDirectory("com.foo", "nope", "1.0"); - assertFalse(configDir.isPresent()); + config = index.findConfiguration("com.foo", "nope", "1.0"); + assertFalse(config.isPresent()); - Optional latest = index.findLatestConfigurationFor("com.foo", "bar"); + Optional latest = index.findLatestConfigurationFor("com.foo", "bar"); assertTrue(latest.isPresent()); - assertEquals(repoPath.resolve("2.0"), latest.get()); + assertEquals(repoPath.resolve("2.0"), latest.get().getDirectory()); + assertTrue(latest.get().isOverride()); } diff --git a/common/graalvm-reachability-metadata/src/test/resources/json/artifact-1/index.json b/common/graalvm-reachability-metadata/src/test/resources/json/artifact-1/index.json index 63370f676..d2f3b3d07 100644 --- a/common/graalvm-reachability-metadata/src/test/resources/json/artifact-1/index.json +++ b/common/graalvm-reachability-metadata/src/test/resources/json/artifact-1/index.json @@ -1,5 +1,5 @@ [ { "module": "com.foo:bar", "tested-versions": ["1.0", "1.1", "1.2", "1.3"], "metadata-version": "1.0" }, - { "module": "com.foo:bar", "tested-versions": ["2.0", "2.1"], "metadata-version": "2.0", "latest": true }, + { "module": "com.foo:bar", "tested-versions": ["2.0", "2.1"], "metadata-version": "2.0", "latest": true, "override": true }, { "module": "com.foo:bar-all", "tested-versions": ["2.0", "2.1"], "metadata-version": "2.0" } ] diff --git a/common/graalvm-reachability-metadata/src/test/resources/repos/repo1/org/foo/index.json b/common/graalvm-reachability-metadata/src/test/resources/repos/repo1/org/foo/index.json index 980fe87e7..70f6d9c33 100644 --- a/common/graalvm-reachability-metadata/src/test/resources/repos/repo1/org/foo/index.json +++ b/common/graalvm-reachability-metadata/src/test/resources/repos/repo1/org/foo/index.json @@ -12,6 +12,7 @@ "1.1" ], "metadata-version": "1.1", - "latest": true + "latest": true, + "override": true } ] 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 637b60cd3..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,7 +58,9 @@ 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" + "org.junit.platform.commons.util.ReflectionUtils", + // https://github.com/graalvm/native-build-tools/issues/300 + "org.junit.platform.reporting.open.xml.OpenTestReportGeneratingListener" }; for (String className : buildTimeInitializedClasses) { config.initializeAtBuildTime(className); diff --git a/common/utils/src/main/java/org/graalvm/buildtools/utils/NativeImageUtils.java b/common/utils/src/main/java/org/graalvm/buildtools/utils/NativeImageUtils.java index 47801c6fb..b0b3a485e 100644 --- a/common/utils/src/main/java/org/graalvm/buildtools/utils/NativeImageUtils.java +++ b/common/utils/src/main/java/org/graalvm/buildtools/utils/NativeImageUtils.java @@ -45,6 +45,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import java.util.Collections; import java.util.List; @@ -72,15 +73,24 @@ public static String nativeImageConfigureFileName() { return "native-image-configure" + GRAALVM_EXE_EXTENSION; } - public static List convertToArgsFile(List cliArgs) { + public static List convertToArgsFile(List cliArgs, Path outputDir) { + return convertToArgsFile(cliArgs, outputDir, Paths.get("")); + } + + public static List convertToArgsFile(List cliArgs, Path outputDir, Path projectDir) { try { - File tmpFile = Files.createTempFile("native-image", "args").toFile(); - tmpFile.deleteOnExit(); + boolean ignored = outputDir.toFile().mkdirs(); + File tmpFile = Files.createTempFile(outputDir, "native-image-", ".args").toFile(); + // tmpFile.deleteOnExit(); cliArgs = cliArgs.stream().map(NativeImageUtils::escapeArg).collect(Collectors.toList()); Files.write(tmpFile.toPath(), cliArgs, StandardCharsets.UTF_8, StandardOpenOption.CREATE); - return Collections.singletonList("@" + tmpFile.getAbsolutePath()); - } catch (IOException e) { + Path resultingPath = tmpFile.toPath().toAbsolutePath(); + if (projectDir != null) { // We know where the project dir is, so want to use relative paths + resultingPath = projectDir.toAbsolutePath().relativize(resultingPath); + } + return Collections.singletonList("@" + resultingPath); + } catch (IOException e) { return Collections.unmodifiableList(cliArgs); } } diff --git a/common/utils/src/main/java/org/graalvm/buildtools/utils/SharedConstants.java b/common/utils/src/main/java/org/graalvm/buildtools/utils/SharedConstants.java index 6498e8d60..e67851a8f 100644 --- a/common/utils/src/main/java/org/graalvm/buildtools/utils/SharedConstants.java +++ b/common/utils/src/main/java/org/graalvm/buildtools/utils/SharedConstants.java @@ -76,5 +76,5 @@ public interface SharedConstants { String AGENT_OUTPUT_DIRECTORY_MARKER = "{output_dir}"; String AGENT_OUTPUT_DIRECTORY_OPTION = "config-output-dir="; String METADATA_REPO_URL_TEMPLATE = "https://github.com/oracle/graalvm-reachability-metadata/releases/download/%1$s/graalvm-reachability-metadata-%1$s.zip"; - String METADATA_REPO_DEFAULT_VERSION = "0.1.0"; + String METADATA_REPO_DEFAULT_VERSION = "0.2.0"; } diff --git a/common/utils/src/test/java/org/graalvm/buildtools/utils/FileUtilsTest.java b/common/utils/src/test/java/org/graalvm/buildtools/utils/FileUtilsTest.java index 0af07030f..c266c2e7a 100644 --- a/common/utils/src/test/java/org/graalvm/buildtools/utils/FileUtilsTest.java +++ b/common/utils/src/test/java/org/graalvm/buildtools/utils/FileUtilsTest.java @@ -131,8 +131,6 @@ void testExtract(@TempDir Path tempDir) throws IOException { assertTrue(Files.exists(tempDir.resolve("index.json"))); assertEquals("[]", String.join("\n", Files.readAllLines(tempDir.resolve("index.json")))); - assertTrue(Files.isDirectory(tempDir.resolve("org"))); - assertTrue(Files.isDirectory(tempDir.resolve("org.graalvm"))); assertTrue(Files.isDirectory(tempDir.resolve("org.graalvm.internal"))); assertTrue(Files.isDirectory(tempDir.resolve("org.graalvm.internal/library-with-reflection"))); assertTrue(Files.exists(tempDir.resolve("org.graalvm.internal/library-with-reflection/index.json"))); diff --git a/common/utils/src/test/resources/graalvm-reachability-metadata.tar.bz2 b/common/utils/src/test/resources/graalvm-reachability-metadata.tar.bz2 deleted file mode 100644 index b57c66fbf..000000000 Binary files a/common/utils/src/test/resources/graalvm-reachability-metadata.tar.bz2 and /dev/null differ diff --git a/common/utils/src/test/resources/graalvm-reachability-metadata.tar.gz b/common/utils/src/test/resources/graalvm-reachability-metadata.tar.gz deleted file mode 100644 index ff230a230..000000000 Binary files a/common/utils/src/test/resources/graalvm-reachability-metadata.tar.gz and /dev/null differ diff --git a/common/utils/src/test/resources/graalvm-reachability-metadata.zip b/common/utils/src/test/resources/graalvm-reachability-metadata.zip index 5b9798dc5..33f9b6da6 100644 Binary files a/common/utils/src/test/resources/graalvm-reachability-metadata.zip and b/common/utils/src/test/resources/graalvm-reachability-metadata.zip differ diff --git a/docs/src/docs/asciidoc/announcement.adoc b/docs/src/docs/asciidoc/announcement.adoc index 1eab3490c..24f797cf1 100644 --- a/docs/src/docs/asciidoc/announcement.adoc +++ b/docs/src/docs/asciidoc/announcement.adoc @@ -144,7 +144,7 @@ Adding our new plugin to the existing _Maven_ project requires adding the follow build-native - build + compile-no-fork package diff --git a/docs/src/docs/asciidoc/gradle-plugin.adoc b/docs/src/docs/asciidoc/gradle-plugin.adoc index 418393a93..53edacef1 100644 --- a/docs/src/docs/asciidoc/gradle-plugin.adoc +++ b/docs/src/docs/asciidoc/gradle-plugin.adoc @@ -12,6 +12,11 @@ For upgrading please take a look at the <>. == Quickstart +[NOTE] +==== +You can find full samples in https://github.com/graalvm/native-build-tools/tree/master/samples[the source repository]. +==== + === Adding the plugin Add following to `plugins` section of your project's `build.gradle` / `build.gradle.kts`: @@ -37,6 +42,8 @@ plugins { } ---- +NOTE: This plugin supplements and heavily relies on regular Java plugins (e.g. `application`, `java-library`, `java` etc). Not having them included in your project will most probably cause errors. + The plugin isn't available on the https://plugins.gradle.org[Gradle Plugin Portal] yet, so you will need to declare a plugin repository in addition: Add the following to your `settings.gradle` / `settings.gradle.kts`: @@ -52,8 +59,9 @@ include::../snippets/gradle/groovy/settings.gradle[tags=plugin-management] include::../snippets/gradle/kotlin/settings.gradle.kts[tags=plugin-management] ---- + [TIP] -.Testing pre-releases +.Testing pre-releases (BROKEN AT THE MOMENT!) ==== You can use development versions of the plugin by adding our snapshot repository instead. Pre-releases are provided for convenience, without any guarantee. [source, groovy, role="multi-language-sample"] @@ -213,6 +221,8 @@ This plugin supports running tests on the https://junit.org/junit5/docs/current/user-guide/[JUnit Platform] as native images. This means that tests will be compiled and executed as native code. +NOTE: The minimum supported version is JUnit 5.8.1 (JUnit Platform 1.8.1, JUnit Jupiter 5.8.1, JUnit Vintage 5.8.1) + In theory, any `TestEngine` supported on the JUnit Platform should be supported by this plugin as long as the programming language used by the `TestEngine` and the programming language used to write the tests is supported in a GraalVM native image. This plugin @@ -226,8 +236,6 @@ Currently, this feature requires the execution of the tests in the classic "JVM" ./gradlew nativeTest ---- -NOTE: This plugin requires JUnit Platform 1.8 or higher. - [[testing-support-disabling]] === Disabling testing support @@ -284,7 +292,7 @@ The same mechanism can be used if you have multiple test tasks for a single test [[agent-support]] == Reflection support and running with the native agent -If your project requires reflection, classpath resources, dynamic proxies or other features requiring explicit native configuration, it may prove helpful to first run your application or tests using the https://www.graalvm.org/reference-manual/native-image/Agent/[`native-image-agent`]. +If your project requires reflection, classpath resources, dynamic proxies or other features requiring explicit native configuration, it may prove helpful to first run your application or tests using the https://www.graalvm.org/reference-manual/native-image/metadata/AutomaticMetadataCollection/[`native-image-agent`]. The Native Image Gradle plugin simplifies generation of the required metadata files by injecting the agent automatically for you (this includes, but is not limited to the reflection file). diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index ef5a02ff3..0789a9d69 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -16,12 +16,27 @@ If you are using alternative build systems, see <>. [[quickstart]] == Quickstart +[NOTE] +==== +You can find full samples in https://github.com/graalvm/native-build-tools/tree/master/samples[the source repository]. +==== + This plugin first requires that you <>. It will then make use of Maven profiles to enable building and testing of native images. @@ -40,7 +45,7 @@ Add the following profile to your `pom.xml` file to register the `native-maven-p build-native - build + compile-no-fork package @@ -70,6 +75,8 @@ If the heuristics fail with the `no main manifest attribute, in target/.ja specified in the `` node of the plugin. When `mvn -Pnative package` completes, an executable is ready for use, generated in the `target` directory of the project. +NOTE: Building native image without attaching to the `package` phase can be done by invoking the forking `compile` goal directly, e.g. `mvn native:compile` + [TIP] .Testing pre-releases ==== @@ -295,6 +302,8 @@ This plugin supports running tests on the https://junit.org/junit5/docs/current/user-guide/[JUnit Platform] as native images. This means that tests will be compiled and executed as native code. +NOTE: The minimum supported version is JUnit 5.8.1 (JUnit Platform 1.8.1, JUnit Jupiter 5.8.1, JUnit Vintage 5.8.1) + In theory, any `TestEngine` supported on the JUnit Platform should be supported by this plugin as long as the programming language used by the `TestEngine` and the programming language used to write the tests is supported in a GraalVM native image. This plugin @@ -312,8 +321,7 @@ Running `mvn -Pnative test` will then build and run native tests. [[testing-support-version-compatibility]] === Version compatibility -This plugin requires JUnit Platform 1.8 or higher and Maven Surefire 2.22.0 or higher to -run tests within a native image. +This plugin requires Maven Surefire 2.22.0 or higher to run tests within a native image. Each version of the Maven Surefire plugin has a dependency on a particular version of the JUnit Platform. You therefore need to ensure that Maven Surefire is using at least version @@ -448,7 +456,7 @@ Please refer to the https://maven.apache.org/plugins/maven-shade-plugin[Maven Sh If your project requires reflection, classpath resources, dynamic proxies or other features requiring explicit native configuration, it may prove helpful to first run your application or tests using the -https://www.graalvm.org/reference-manual/native-image/Agent/[`native-image-agent`]. +https://www.graalvm.org/reference-manual/native-image/metadata/AutomaticMetadataCollection/[`native-image-agent`]. The Native Image Maven plugin simplifies generation of the required configuration files by injecting the agent automatically for you (this includes, but is not limited to the diff --git a/docs/src/docs/snippets/gradle/groovy/build.gradle b/docs/src/docs/snippets/gradle/groovy/build.gradle index ff96c78c3..009e07f68 100644 --- a/docs/src/docs/snippets/gradle/groovy/build.gradle +++ b/docs/src/docs/snippets/gradle/groovy/build.gradle @@ -115,17 +115,17 @@ graalvmNative { // Main options imageName = 'application' // The name of the native image, defaults to the project name mainClass = 'org.test.Main' // The main class to use, defaults to the application.mainClass - debug = true // Determines if debug info should be generated, defaults to false + debug = true // Determines if debug info should be generated, defaults to false (alternatively add --debug-native to the CLI) verbose = true // Add verbose output, defaults to false fallback = true // Sets the fallback mode of native-image, defaults to false sharedLibrary = false // Determines if image is a shared library, defaults to false if `java-library` plugin isn't included - quickBuild = false // Determines if image is being built in quick build mode (alternatively use GRAALVM_QUICK_BUILD environment variable) + quickBuild = false // Determines if image is being built in quick build mode (alternatively use GRAALVM_QUICK_BUILD environment variable, or add --native-quick-build to the CLI) richOutput = false // Determines if native-image building should be done with rich output systemProperties = [name1: 'value1', name2: 'value2'] // Sets the system properties to use for the native image builder configurationFileDirectories.from(file('src/my-config')) // Adds a native image configuration file directory, containing files like reflection configuration - excludeConfig.put("org.example.test", ["META-INF/native-image/*", "config/*"]) // Excludes configuration that matches one of given regexes from JAR of dependency with said coordinates. - excludeConfig.put(file("path/to/artifact.jar"), listOf("META-INF/native-image/*", "config/*")) + excludeConfig.put("org.example.test:artifact:version", ["^/META-INF/native-image/.*", "^/config/.*"]) // Excludes configuration that matches one of given regexes from JAR of dependency with said coordinates. + excludeConfig.put(file("path/to/artifact.jar"), listOf("^/META-INF/native-image/.*", "^/config/.*")) // Advanced options buildArgs.add('-H:Extra') // Passes '-H:Extra' to the native image builder options. This can be used to pass parameters which are not directly supported by this extension diff --git a/docs/src/docs/snippets/gradle/kotlin/build.gradle.kts b/docs/src/docs/snippets/gradle/kotlin/build.gradle.kts index e30f416a1..a51b49fa1 100644 --- a/docs/src/docs/snippets/gradle/kotlin/build.gradle.kts +++ b/docs/src/docs/snippets/gradle/kotlin/build.gradle.kts @@ -116,17 +116,17 @@ graalvmNative { // Main options imageName.set("application") // The name of the native image, defaults to the project name mainClass.set("org.test.Main") // The main class to use, defaults to the application.mainClass - debug.set(true) // Determines if debug info should be generated, defaults to false + debug.set(true) // Determines if debug info should be generated, defaults to false (alternatively add --debug-native to the CLI) verbose.set(true) // Add verbose output, defaults to false fallback.set(true) // Sets the fallback mode of native-image, defaults to false sharedLibrary.set(false) // Determines if image is a shared library, defaults to false if `java-library` plugin isn't included - quickBuild.set(false) // Determines if image is being built in quick build mode (alternatively use GRAALVM_QUICK_BUILD environment variable) + quickBuild.set(false) // Determines if image is being built in quick build mode (alternatively use GRAALVM_QUICK_BUILD environment variable, or add --native-quick-build to the CLI) richOutput.set(false) // Determines if native-image building should be done with rich output systemProperties.putAll(mapOf("name1" to "value1", "name2" to "value2")) // Sets the system properties to use for the native image builder configurationFileDirectories.from(file("src/my-config")) // Adds a native image configuration file directory, containing files like reflection configuration - excludeConfig.put("org.example.test", listOf("META-INF/native-image/*", "config/*")) // Excludes configuration that matches one of given regexes from JAR of dependency with said coordinates. - excludeConfig.put(file("path/to/artifact.jar"), listOf("META-INF/native-image/*", "config/*")) + excludeConfig.put("org.example.test:artifact:version", listOf("^/META-INF/native-image/.*", "^/config/.*")) // Excludes configuration that matches one of given regexes from JAR of dependency with said coordinates. + excludeConfig.put(file("path/to/artifact.jar"), listOf("^/META-INF/native-image/.*", "^/config/.*")) // Advanced options buildArgs.add("-H:Extra") // Passes '-H:Extra' to the native image builder options. This can be used to pass parameters which are not directly supported by this extension diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ed2f7379b..72e405f30 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,12 +1,12 @@ [versions] # Project versions -nativeBuildTools = "0.9.13" +nativeBuildTools = "0.9.14" # External dependencies spock = "2.1-groovy-3.0" -maven = "3.8.5" +maven = "3.8.6" mavenAnnotations = "3.6.4" -mavenEmbedder = "3.8.3" +mavenEmbedder = "3.8.6" mavenWagon = "3.4.3" graalvm = "22.0.0" jackson = "2.13.3" @@ -15,7 +15,6 @@ junitJupiter = "5.8.1" aether = "1.1.0" slf4j = "1.7.9" groovy = "3.0.11" -jgit = "5.12.0.202106070339-r" jetty = "11.0.11" [libraries] @@ -54,7 +53,4 @@ maven-wagon-provider = { module = "org.apache.maven.wagon:wagon-provider-api", v slf4j-simple = { module = "org.slf4j:slf4j-simple", version.ref = "slf4j" } -jgit = { module = "org.eclipse.jgit:org.eclipse.jgit", version.ref = "jgit" } -jsch = { module = "org.eclipse.jgit:org.eclipse.jgit.ssh.jsch", version.ref="jgit" } - jetty-server = { module = "org.eclipse.jetty:jetty-server", version.ref = "jetty" } diff --git a/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/JavaApplicationFunctionalTest.groovy b/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/JavaApplicationFunctionalTest.groovy index 4af8aadc2..cc814a2f9 100644 --- a/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/JavaApplicationFunctionalTest.groovy +++ b/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/JavaApplicationFunctionalTest.groovy @@ -188,4 +188,32 @@ class JavaApplicationFunctionalTest extends AbstractFunctionalTest { } + @Issue("https://github.com/graalvm/native-build-tools/issues/275") + def "can pass environment variables to the builder process"() { + def nativeApp = file("build/native/nativeCompile/java-application") + + given: + withSample("java-application") + + buildFile << """ + graalvmNative.binaries.all { + buildArgs.add("--initialize-at-build-time=org.graalvm.demo.Application") + environmentVariables.put('CUSTOM_MESSAGE', 'Hello, custom message!') + } + """.stripIndent() + + when: + run 'nativeCompile' + + then: + nativeApp.exists() + + when: + def process = execute(nativeApp) + + then: + process.output.contains "Hello, custom message!" + + } + } diff --git a/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/JavaApplicationWithAgentFunctionalTest.groovy b/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/JavaApplicationWithAgentFunctionalTest.groovy index e98659f09..6ec8ace24 100644 --- a/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/JavaApplicationWithAgentFunctionalTest.groovy +++ b/native-gradle-plugin/src/functionalTest/groovy/org/graalvm/buildtools/gradle/JavaApplicationWithAgentFunctionalTest.groovy @@ -42,7 +42,6 @@ package org.graalvm.buildtools.gradle import org.graalvm.buildtools.gradle.fixtures.AbstractFunctionalTest -import spock.lang.Issue import spock.lang.Unroll class JavaApplicationWithAgentFunctionalTest extends AbstractFunctionalTest { @@ -175,4 +174,39 @@ class JavaApplicationWithAgentFunctionalTest extends AbstractFunctionalTest { where: junitVersion = System.getProperty('versions.junit') } + + @Unroll("plugin supports configuration cache (JUnit Platform #junitVersion)") + def "supports configuration cache"() { + debug = true + var metadata_dir = 'src/main/resources/META-INF/native-image' + given: + withSample("java-application-with-reflection") + + when: + run 'run', '-Pagent', '--configuration-cache' + + then: + tasks { + succeeded ':run' + doesNotContain ':jar' + } + + and: + ['jni', 'proxy', 'reflect', 'resource', 'serialization'].each { name -> + assert file("build/native/agent-output/run/${name}-config.json").exists() + } + + when: + run'run', '-Pagent', '--configuration-cache', '--rerun-tasks' + + then: + tasks { + succeeded ':run' + doesNotContain ':jar' + } + outputContains "Reusing configuration cache" + + where: + junitVersion = System.getProperty('versions.junit') + } } 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 70b887e25..27a6a9f4a 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 @@ -54,8 +54,8 @@ import org.graalvm.buildtools.gradle.internal.DefaultTestBinaryConfig; import org.graalvm.buildtools.gradle.internal.DeprecatedNativeImageOptions; import org.graalvm.buildtools.gradle.internal.GraalVMLogger; -import org.graalvm.buildtools.gradle.internal.GradleUtils; import org.graalvm.buildtools.gradle.internal.GraalVMReachabilityMetadataService; +import org.graalvm.buildtools.gradle.internal.GradleUtils; import org.graalvm.buildtools.gradle.internal.NativeConfigurations; import org.graalvm.buildtools.gradle.internal.agent.AgentConfigurationFactory; import org.graalvm.buildtools.gradle.tasks.BuildNativeImageTask; @@ -66,6 +66,7 @@ import org.graalvm.buildtools.gradle.tasks.actions.MergeAgentFilesAction; import org.graalvm.buildtools.gradle.tasks.actions.ProcessGeneratedGraalResourceFilesAction; import org.graalvm.buildtools.utils.SharedConstants; +import org.graalvm.reachability.DirectoryConfiguration; import org.gradle.api.Action; import org.gradle.api.NamedDomainObjectContainer; import org.gradle.api.Plugin; @@ -110,21 +111,29 @@ import org.gradle.process.JavaForkOptions; import org.gradle.util.GFileUtils; +import javax.annotation.Nonnull; import javax.inject.Inject; import java.io.File; import java.net.URI; import java.net.URISyntaxException; import java.nio.file.Path; +import java.util.AbstractMap; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.regex.Pattern; import java.util.stream.Collectors; +import static org.graalvm.buildtools.gradle.internal.ConfigurationCacheSupport.serializablePredicateOf; +import static org.graalvm.buildtools.gradle.internal.ConfigurationCacheSupport.serializableSupplierOf; +import static org.graalvm.buildtools.gradle.internal.ConfigurationCacheSupport.serializableTransformerOf; import static org.graalvm.buildtools.gradle.internal.GradleUtils.transitiveProjectArtifacts; import static org.graalvm.buildtools.gradle.internal.NativeImageExecutableLocator.graalvmHomeProvider; import static org.graalvm.buildtools.utils.SharedConstants.AGENT_PROPERTY; @@ -170,7 +179,7 @@ public FileSystemOperations getFileOperations() { @Override - public void apply(Project project) { + public void apply(@Nonnull Project project) { Provider nativeImageServiceProvider = NativeImageService.registerOn(project); logger = GraalVMLogger.of(project.getLogger()); @@ -194,7 +203,7 @@ public void apply(Project project) { private void instrumentTasksWithAgent(Project project, DefaultGraalVmExtension graalExtension) { Provider agentMode = agentProperty(project, graalExtension.getAgent()); - Predicate taskPredicate = graalExtension.getAgent().getTasksToInstrumentPredicate().get(); + Predicate taskPredicate = graalExtension.getAgent().getTasksToInstrumentPredicate().getOrElse(serializablePredicateOf(t -> true)); project.getTasks().configureEach(t -> { if (isTaskInstrumentableByAgent(t) && taskPredicate.test(t)) { configureAgent(project, agentMode, graalExtension, getExecOperations(), getFileOperations(), t, (JavaForkOptions) t); @@ -231,7 +240,7 @@ private void configureJavaProject(Project project, Provider deprecateExtension(project, mainOptions, DEPRECATED_NATIVE_BUILD_EXTENSION, "main"); project.getPlugins().withId("application", p -> mainOptions.getMainClass().convention( - project.getExtensions().findByType(JavaApplication.class).getMainClass() + Objects.requireNonNull(project.getExtensions().findByType(JavaApplication.class)).getMainClass() )); project.getPlugins().withId("java-library", p -> mainOptions.getSharedLibrary().convention(true)); @@ -305,6 +314,7 @@ private void configureAutomaticTaskCreation(Project project, t.getOutputFile().map(f -> f.getAsFile().getParentFile()) )); configureJvmReachabilityConfigurationDirectories(project, graalExtension, options, sourceSet); + configureJvmReachabilityExcludeConfigArgs(project, graalExtension, options, sourceSet); }); } @@ -324,9 +334,9 @@ private void configureJvmReachabilityConfigurationDirectories(Project project, G Configuration classpath = project.getConfigurations().getByName(sourceSet.getRuntimeClasspathConfigurationName()); Set excludedModules = repositoryExtension.getExcludedModules().getOrElse(Collections.emptySet()); Map forcedVersions = repositoryExtension.getModuleToConfigVersion().getOrElse(Collections.emptyMap()); - return serviceProvider.map(repo -> repo.findConfigurationDirectoriesFor(query -> classpath.getIncoming().getResolutionResult().allComponents(component -> { + return serviceProvider.map(repo -> repo.findConfigurationsFor(query -> classpath.getIncoming().getResolutionResult().allComponents(component -> { ModuleVersionIdentifier moduleVersion = component.getModuleVersion(); - String module = moduleVersion.getGroup() + ":" + moduleVersion.getName(); + String module = Objects.requireNonNull(moduleVersion).getGroup() + ":" + moduleVersion.getName(); if (!excludedModules.contains(module)) { query.forArtifact(artifact -> { artifact.gav(module + ":" + moduleVersion.getVersion()); @@ -337,7 +347,7 @@ private void configureJvmReachabilityConfigurationDirectories(Project project, G } query.useLatestConfigWhenVersionIsUntested(); })).stream() - .map(Path::toAbsolutePath) + .map(configuration -> configuration.getDirectory().toAbsolutePath()) .map(Path::toFile) .collect(Collectors.toList())); } @@ -346,6 +356,47 @@ private void configureJvmReachabilityConfigurationDirectories(Project project, G })); } + private void configureJvmReachabilityExcludeConfigArgs(Project project, GraalVMExtension graalExtension, NativeImageOptions options, SourceSet sourceSet) { + GraalVMReachabilityMetadataRepositoryExtension repositoryExtension = reachabilityExtensionOn(graalExtension); + Provider serviceProvider = project.getGradle() + .getSharedServices() + .registerIfAbsent("nativeConfigurationService", GraalVMReachabilityMetadataService.class, spec -> { + LogLevel logLevel = determineLogLevel(); + spec.getParameters().getLogLevel().set(logLevel); + spec.getParameters().getUri().set(repositoryExtension.getUri()); + spec.getParameters().getCacheDir().set(new File(project.getGradle().getGradleUserHomeDir(), "native-build-tools/repositories")); + }); + options.getExcludeConfig().putAll(repositoryExtension.getEnabled().flatMap(enabled -> { + if (enabled) { + if (repositoryExtension.getUri().isPresent()) { + Configuration classpath = project.getConfigurations().getByName(sourceSet.getRuntimeClasspathConfigurationName()); + Set excludedModules = repositoryExtension.getExcludedModules().getOrElse(Collections.emptySet()); + Map forcedVersions = repositoryExtension.getModuleToConfigVersion().getOrElse(Collections.emptyMap()); + return serviceProvider.map(repo -> classpath.getIncoming().getResolutionResult().getAllComponents().stream().flatMap(component -> { + ModuleVersionIdentifier moduleVersion = component.getModuleVersion(); + return repo.findConfigurationsFor(query -> { + String module = Objects.requireNonNull(moduleVersion).getGroup() + ":" + moduleVersion.getName(); + if (!excludedModules.contains(module)) { + query.forArtifact(artifact -> { + artifact.gav(module + ":" + moduleVersion.getVersion()); + if (forcedVersions.containsKey(module)) { + artifact.forceConfigVersion(forcedVersions.get(module)); + } + }); + } + query.useLatestConfigWhenVersionIsUntested(); + }).stream() + .filter(DirectoryConfiguration::isOverride) + .map(configuration -> new AbstractMap.SimpleEntry<>( + moduleVersion.getGroup() + ":" + moduleVersion.getName() + ":" + moduleVersion.getVersion(), + Arrays.asList("^/META-INF/native-image/.*"))); + }).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))); + } + } + return project.getProviders().provider(Collections::emptyMap); + })); + } + private static LogLevel determineLogLevel() { LogLevel logLevel = LogLevel.DEBUG; String loggingProperty = System.getProperty(CONFIG_REPO_LOGLEVEL); @@ -428,7 +479,7 @@ private void configureNativeConfigurationRepo(ExtensionAware graalvmNative) { try { return new URI(String.format(METADATA_REPO_URL_TEMPLATE, v)); } catch (URISyntaxException e) { - return null; + throw new RuntimeException(e); } })); configurationRepository.getExcludedModules().convention(Collections.emptySet()); @@ -518,13 +569,13 @@ private static Provider agentProperty(Project project, AgentOptions opti return project.getProviders() .gradleProperty(AGENT_PROPERTY) .forUseAtConfigurationTime() - .map(v -> { + .map(serializableTransformerOf(v -> { if (!v.isEmpty()) { return v; } return options.getDefaultMode().get(); - }) - .orElse(options.getEnabled().map(enabled -> enabled ? options.getDefaultMode().get() : "disabled")); + })) + .orElse(options.getEnabled().map(serializableTransformerOf(enabled -> enabled ? options.getDefaultMode().get() : "disabled"))); } private static void registerServiceProvider(Project project, Provider nativeImageServiceProvider) { @@ -562,7 +613,7 @@ private static NativeConfigurations createNativeConfigurations(Project project, for (Attribute attribute : baseAttributes.keySet()) { Attribute attr = (Attribute) attribute; Object value = baseAttributes.getAttribute(attr); - attrs.attribute(attr, value); + attrs.attribute(attr, Objects.requireNonNull(value)); } }); }); @@ -613,8 +664,8 @@ private static NativeImageOptions createTestOptions(GraalVMExtension graalExtens private static void addExcludeConfigArg(List args, Path jarPath, List listOfResourcePatterns) { listOfResourcePatterns.forEach(resourcePattern -> { args.add("--exclude-config"); - args.add(jarPath.toAbsolutePath().toString()); - args.add(String.format("\"%s\"", resourcePattern)); + args.add(Pattern.quote(jarPath.toAbsolutePath().toString())); + args.add(String.format("%s", resourcePattern)); }); } @@ -653,7 +704,12 @@ private static void setupExtensionConfigExcludes(NativeImageOptions options, Nat } private static List agentSessionDirectories(Directory outputDirectory) { - return Arrays.stream(outputDirectory.getAsFile().listFiles(file -> file.isDirectory() && file.getName().startsWith("session-"))).map(File::getAbsolutePath).collect(Collectors.toList()); + return Arrays.stream(Objects.requireNonNull( + outputDirectory.getAsFile() + .listFiles(file -> file.isDirectory() && file.getName().startsWith("session-")) + ) + ).map(File::getAbsolutePath) + .collect(Collectors.toList()); } private void configureAgent(Project project, @@ -663,22 +719,29 @@ private void configureAgent(Project project, FileSystemOperations fileOperations, Task taskToInstrument, JavaForkOptions javaForkOptions) { - logger.lifecycle("Instrumenting task with the native-image-agent: " + taskToInstrument.getName()); Provider agentConfiguration = AgentConfigurationFactory.getAgentConfiguration(agentMode, graalExtension.getAgent()); - + //noinspection Convert2Lambda + taskToInstrument.doFirst(new Action() { + @Override + public void execute(@Nonnull Task task) { + if (agentConfiguration.get().isEnabled()) { + logger.logOnce("Instrumenting task with the native-image-agent: " + task.getName()); + } + } + }); AgentCommandLineProvider cliProvider = project.getObjects().newInstance(AgentCommandLineProvider.class); - cliProvider.getInputFiles().from(agentConfiguration.map(AgentConfiguration::getAgentFiles)); - cliProvider.getEnabled().set(agentConfiguration.map(AgentConfiguration::isEnabled)); + cliProvider.getInputFiles().from(agentConfiguration.map(serializableTransformerOf(AgentConfiguration::getAgentFiles))); + cliProvider.getEnabled().set(agentConfiguration.map(serializableTransformerOf(AgentConfiguration::isEnabled))); cliProvider.getFilterableEntries().set(graalExtension.getAgent().getFilterableEntries()); cliProvider.getAgentMode().set(agentMode); Provider outputDir = AgentConfigurationFactory.getAgentOutputDirectoryForTask(project.getLayout(), taskToInstrument.getName()); - Provider isMergingEnabled = agentConfiguration.map(AgentConfiguration::isEnabled); - Provider agentModeProvider = agentConfiguration.map(AgentConfiguration::getAgentMode); - Provider> mergeOutputDirs = outputDir.map(dir -> Collections.singletonList(dir.getAsFile().getAbsolutePath())); - Provider> mergeInputDirs = outputDir.map(NativeImagePlugin::agentSessionDirectories); + Provider isMergingEnabled = agentConfiguration.map(serializableTransformerOf(AgentConfiguration::isEnabled)); + Provider agentModeProvider = agentConfiguration.map(serializableTransformerOf(AgentConfiguration::getAgentMode)); + Supplier> mergeInputDirs = serializableSupplierOf(() -> outputDir.map(serializableTransformerOf(NativeImagePlugin::agentSessionDirectories)).get()); + Supplier> mergeOutputDirs = serializableSupplierOf(() -> outputDir.map(serializableTransformerOf(dir -> Collections.singletonList(dir.getAsFile().getAbsolutePath()))).get()); cliProvider.getOutputDirectory().set(outputDir); - cliProvider.getAgentOptions().set(agentConfiguration.map(AgentConfiguration::getAgentCommandLine)); + cliProvider.getAgentOptions().set(agentConfiguration.map(serializableTransformerOf(AgentConfiguration::getAgentCommandLine))); javaForkOptions.getJvmArgumentProviders().add(cliProvider); taskToInstrument.doLast(new MergeAgentFilesAction( @@ -690,8 +753,7 @@ private void configureAgent(Project project, mergeInputDirs, mergeOutputDirs, graalExtension.getToolchainDetection(), - execOperations, - project.getLogger())); + execOperations)); taskToInstrument.doLast(new CleanupAgentFilesAction(mergeInputDirs, fileOperations)); @@ -718,7 +780,7 @@ private CleanupTestIdsDirectory(DirectoryProperty directory) { } @Override - public void execute(Task task) { + public void execute(@Nonnull Task task) { File dir = directory.getAsFile().get(); if (dir.exists()) { GFileUtils.deleteDirectory(dir); diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImageService.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImageService.java index 7d147d8cf..4f6d95b05 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImageService.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImageService.java @@ -41,6 +41,7 @@ package org.graalvm.buildtools.gradle; +import org.graalvm.buildtools.gradle.internal.GraalVMLogger; import org.gradle.api.Project; import org.gradle.api.provider.Provider; import org.gradle.api.services.BuildService; @@ -52,7 +53,9 @@ public static Provider registerOn(Project project) { return project.getGradle() .getSharedServices() .registerIfAbsent("nativeImage", NativeImageService.class, - spec -> spec.getMaxParallelUsages().set(1 + Runtime.getRuntime().availableProcessors() / 16)); - + spec -> { + GraalVMLogger.newBuild(); + spec.getMaxParallelUsages().set(1 + Runtime.getRuntime().availableProcessors() / 16); + }); } } diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/GraalVMExtension.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/GraalVMExtension.java index dd7089704..d6d09c22e 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/GraalVMExtension.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/GraalVMExtension.java @@ -62,6 +62,8 @@ public interface GraalVMExtension { * to disable automatic test support, especially in cases * where the test framework doesn't allow testing within * a native image. + * + * @return is the test support active */ Property getTestSupport(); @@ -76,17 +78,22 @@ public interface GraalVMExtension { * Returns the native image configurations used to generate images. * By default, this plugin creates two images, one called "main" for * the main application and another one called "test" for tests. + * + * @return configuration for binaries */ NamedDomainObjectContainer getBinaries(); /** * Configures the native image options. + * + * @param spec specification for binary */ void binaries(Action> spec); /** * Registers a new native image binary with testing support. * + * @param name the name of the binary * @param spec the test image configuration */ void registerTestBinary(String name, Action spec); @@ -94,6 +101,8 @@ public interface GraalVMExtension { /** * Property driving the detection of toolchains which support building native images. * The default is true. + * + * @return is toolchain detection on */ Property getToolchainDetection(); diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/GraalVMReachabilityMetadataRepositoryExtension.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/GraalVMReachabilityMetadataRepositoryExtension.java index 89d12dcc1..904c8f4e1 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/GraalVMReachabilityMetadataRepositoryExtension.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/GraalVMReachabilityMetadataRepositoryExtension.java @@ -55,6 +55,7 @@ public interface GraalVMReachabilityMetadataRepositoryExtension { /** * Property used to determine if the reachability metadata * repository should be used. + * * @return the enabled property */ Property getEnabled(); @@ -81,6 +82,7 @@ public interface GraalVMReachabilityMetadataRepositoryExtension { * The set of modules for which we don't want to use the * configuration found in the repository. Modules must be * declared with the `groupId:artifactId` syntax. + * * @return the set of excluded modules */ SetProperty getExcludedModules(); @@ -88,6 +90,7 @@ public interface GraalVMReachabilityMetadataRepositoryExtension { /** * A map from a module (org.group:artifact) to configuration * repository config version. + * * @return the map of modules to forced configuration versions */ MapProperty getModuleToConfigVersion(); @@ -95,7 +98,9 @@ public interface GraalVMReachabilityMetadataRepositoryExtension { /** * Convenience method to use a String for the URI * property. + * * @param uri the URI + * @throws URISyntaxException if URL is malformed */ default void uri(String uri) throws URISyntaxException { getUri().set(new URI(uri)); @@ -103,6 +108,7 @@ default void uri(String uri) throws URISyntaxException { /** * Convenience method to use a URI for the property. + * * @param file a file */ default void uri(File file) { diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/NativeImageOptions.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/NativeImageOptions.java index 797473bc5..0a24f1419 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/NativeImageOptions.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/NativeImageOptions.java @@ -107,6 +107,15 @@ public interface NativeImageOptions extends Named { @Input MapProperty getSystemProperties(); + /** + * Returns the environment variables which will be used by the native-image builder process. + * @return the environment variables. Returns an empty map when there are no environment variables. + * + * @since 0.9.14 + */ + @Input + MapProperty getEnvironmentVariables(); + /** * Returns the classpath for the native-image building. * @@ -182,6 +191,8 @@ public interface NativeImageOptions extends Named { /** * Returns the toolchain used to invoke native-image. Currently pointing * to a Java launcher due to Gradle limitations. + * + * @return the detected java launcher */ @Nested @Optional diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/NativeResourcesOptions.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/NativeResourcesOptions.java index 9fe25a56e..4addefc70 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/NativeResourcesOptions.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/NativeResourcesOptions.java @@ -66,6 +66,8 @@ public void autodetect() { * The list of bundles to include in the generated resources file. * The contents of this property is used to generate the "bundles" * section of the resource-config.json file + * + * @return the list of bundles */ @Input public abstract ListProperty getBundles(); @@ -74,9 +76,9 @@ public void autodetect() { * The list of resources to include, as Java regular expressions. * The contents of this property is used to generate the "resources" : "includes" * section of the resource-config.json file. - * * It will be merged with detected resources, if any. * + * @return the list of resources to include */ @Input public abstract ListProperty getIncludedPatterns(); @@ -85,9 +87,9 @@ public void autodetect() { * The list of resources to exclude, as Java regular expressions. * The contents of this property is used to generate the "resources" : "excludes" * section of the resource-config.json file. - * * It will be merged with detected resources, if any. * + * @return the list of resources to exclude */ @Input public abstract ListProperty getExcludedPatterns(); diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/ResourceDetectionOptions.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/ResourceDetectionOptions.java index d20139a99..952b4fcb2 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/ResourceDetectionOptions.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/ResourceDetectionOptions.java @@ -50,6 +50,8 @@ public abstract class ResourceDetectionOptions { * Determines if the resources should be detected from classpath. * If this property is set to true, then Gradle will automatically * detect resources to include from conventional places like src/main/resources. + * + * @return if resources should be detected from the classpath */ @Input public abstract Property getEnabled(); @@ -57,8 +59,9 @@ public abstract class ResourceDetectionOptions { /** * Determines if detection should be limited to project dependencies, in * which case external dependencies will not be scanned. - * * Default value is true. + * + * @return if detection should be limited to the project dependencies */ @Input public abstract Property getRestrictToProjectDependencies(); @@ -69,6 +72,7 @@ public abstract class ResourceDetectionOptions { * that classpath entry (e.g jar). By default, this behavior is set to false, * meaning that if such a file is present, detection is disabled for this * particular classpath entry. + * * @return the ignore property */ @Input @@ -77,6 +81,8 @@ public abstract class ResourceDetectionOptions { /** * Returns the list of regular expressions which will be used to exclude * resources from detection. + * + * @return a list of regular expressions for resources exclusion */ @Input public abstract SetProperty getDetectionExclusionPatterns(); @@ -85,6 +91,8 @@ public abstract class ResourceDetectionOptions { * Adds the default resource excludes for detection, which can be useful if * you want to add more excludes but still want the conventional ones to be * added. + * + * @return resource detection options */ public ResourceDetectionOptions addDefaultDetectionExclusions() { getDetectionExclusionPatterns().addAll(SharedConstants.DEFAULT_EXCLUDES_FOR_RESOURCE_DETECTION); diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/agent/AgentOptions.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/agent/AgentOptions.java index 4726f1d72..795822638 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/agent/AgentOptions.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/dsl/agent/AgentOptions.java @@ -57,6 +57,7 @@ public interface AgentOptions { /** * Contains configuration of supported agent modes. + * @return agent modes */ @Nested AgentModeOptions getModes(); @@ -67,6 +68,7 @@ default void modes(Action spec) { /** * The default agent mode name when the agent is in use. + * @return default agent mode */ @Input @Optional @@ -74,6 +76,7 @@ default void modes(Action spec) { /** * Enables the agent. + * @return is the agent enabled */ @Input @Optional @@ -81,6 +84,7 @@ default void modes(Action spec) { /** * Caller-filter files that will be passed to the agent. + * @return caller filter files */ @InputFiles @Optional @@ -88,6 +92,7 @@ default void modes(Action spec) { /** * Access-filter files that will be passed to the agent. + * @return access filter files */ @InputFiles @Optional @@ -95,12 +100,14 @@ default void modes(Action spec) { /** * Toggles the builtin agent caller filter. + * @return builtin caller filter */ @Optional Property getBuiltinCallerFilter(); /** * Toggles the builtin agent heuristic filter. + * @return is builtin heuristic filter enabled */ @Optional Property getBuiltinHeuristicFilter(); @@ -108,6 +115,7 @@ default void modes(Action spec) { /** * Toggles the experimental support for predefined classes. + * @return is experimental support for predefined classes enabled */ @Optional Property getEnableExperimentalPredefinedClasses(); @@ -115,6 +123,7 @@ default void modes(Action spec) { /** * Toggles the experimental support for unsafe allocation tracing. + * @return is experimental support for unsafe allocation tracing enabled */ @Optional Property getEnableExperimentalUnsafeAllocationTracing(); @@ -122,12 +131,14 @@ default void modes(Action spec) { /** * Toggles the distinction between queried and used metadata. + * @return queried or used metadata */ @Optional Property getTrackReflectionMetadata(); /** * Configuration of the metadata copy task. + * @return configuration of the metadata copy task */ @Nested MetadataCopyOptions getMetadataCopy(); @@ -138,6 +149,7 @@ default void metadataCopy(Action spec) { /** * Specifies prefixes that will be used to further filter files produced by the agent. + * @return filterable entries */ @Input @Optional 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 23bb3c9c9..ba2cf0edb 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,7 @@ import org.graalvm.buildtools.utils.SharedConstants; import org.gradle.api.Action; import org.gradle.api.file.ConfigurableFileCollection; +import org.gradle.api.logging.Logging; import org.gradle.api.model.ObjectFactory; import org.gradle.api.provider.ListProperty; import org.gradle.api.provider.MapProperty; @@ -78,6 +79,8 @@ */ @SuppressWarnings({"unused", "UnusedReturnValue"}) public abstract class BaseNativeImageOptions implements NativeImageOptions { + private static final GraalVMLogger LOGGER = GraalVMLogger.of(Logging.getLogger(BaseNativeImageOptions.class)); + private final String name; @Override @@ -122,6 +125,15 @@ public String getName() { @Input public abstract MapProperty getSystemProperties(); + /** + * Returns the environment variables which will be used by the native-image builder process. + * @return the environment variables. Returns an empty map when there are no environment variables. + * + * @since 0.9.14 + */ + @Override + public abstract MapProperty getEnvironmentVariables(); + /** * Returns the classpath for the native-image building. * @@ -240,7 +252,13 @@ public BaseNativeImageOptions(String name, getDebug().convention(false); getFallback().convention(false); getVerbose().convention(false); - getQuickBuild().convention(false); + getQuickBuild().convention(providers.environmentVariable("GRAALVM_QUICK_BUILD").map(env -> { + LOGGER.logOnce("Quick build environment variable is set."); + if (env.isEmpty()) { + return true; + } + return Boolean.parseBoolean(env); + }).orElse(false)); getRichOutput().convention(!SharedConstants.IS_CI && !SharedConstants.IS_WINDOWS && !SharedConstants.IS_DUMB_TERM && !SharedConstants.NO_COLOR); getSharedLibrary().convention(false); getImageName().convention(defaultImageName); diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/ConfigurationCacheSupport.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/ConfigurationCacheSupport.java new file mode 100644 index 000000000..ffc491755 --- /dev/null +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/ConfigurationCacheSupport.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 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.gradle.api.Transformer; + +import java.io.Serializable; +import java.util.function.Predicate; +import java.util.function.Supplier; + +/** + * Helper class to deal with Gradle configuration cache. + */ +public class ConfigurationCacheSupport { + /** + * Generates a serializable supplier lambda. + * @param supplier the supplier + * @return a serializable supplier + * @param the type of the supplier + */ + public static Supplier serializableSupplierOf(SerializableSupplier supplier) { + return supplier; + } + + /** + * Generates a serializable predicate lambda. + * @param predicate the predicate + * @return a serializable predicate + * @param the type of the predicate + */ + public static Predicate serializablePredicateOf(SerializablePredicate predicate) { + return predicate; + } + + /** + * Generates a serializable transformer lambda. + * @param transformer the transformer + * @return a serializable transformer + * @param the output type of the transformer + * @param the input type of the transformer + */ + public static Transformer serializableTransformerOf(SerializableTransformer transformer) { + return transformer; + } + + public interface SerializableSupplier extends Supplier, Serializable { + + } + + public interface SerializablePredicate extends Predicate, Serializable { + + } + + public interface SerializableTransformer extends Transformer, Serializable { + + } + +} 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 f61a785f8..2e91a9fa4 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 @@ -59,9 +59,9 @@ import java.util.Arrays; public abstract class DefaultGraalVmExtension implements GraalVMExtension { - private final NamedDomainObjectContainer nativeImages; - private final NativeImagePlugin plugin; - private final Project project; + private final transient NamedDomainObjectContainer nativeImages; + private final transient NativeImagePlugin plugin; + private final transient Project project; private final Property defaultJavaLauncher; @Inject @@ -76,12 +76,11 @@ public DefaultGraalVmExtension(NamedDomainObjectContainer na nativeImages.configureEach(options -> options.getJavaLauncher().convention(defaultJavaLauncher)); getTestSupport().convention(true); AgentOptions agentOpts = getAgent(); - agentOpts.getTasksToInstrumentPredicate().convention(t -> true); agentOpts.getDefaultMode().convention("standard"); agentOpts.getEnabled().convention(false); agentOpts.getModes().getConditional().getParallel().convention(true); agentOpts.getMetadataCopy().getMergeWithExisting().convention(false); - agentOpts.getFilterableEntries().convention(Arrays.asList("org.gradle.", "java.", "org.junit.")); + agentOpts.getFilterableEntries().convention(Arrays.asList("org.gradle.", "org.junit.")); agentOpts.getBuiltinHeuristicFilter().convention(true); agentOpts.getBuiltinCallerFilter().convention(true); agentOpts.getEnableExperimentalPredefinedClasses().convention(false); 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 index 1a3072e17..aeb7623e9 100644 --- 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 @@ -129,6 +129,11 @@ public MapProperty getSystemProperties() { return warnAboutDeprecation(delegate::getSystemProperties); } + @Override + public MapProperty getEnvironmentVariables() { + return warnAboutDeprecation(delegate::getEnvironmentVariables); + } + @Override @Classpath @InputFiles diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/GraalVMLogger.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/GraalVMLogger.java index 20610427a..336120d08 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/GraalVMLogger.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/GraalVMLogger.java @@ -43,10 +43,21 @@ import org.gradle.api.logging.Logger; +import java.util.HashSet; +import java.util.Set; + /** * Wraps the Gradle logger with a minimal API surface. */ public final class GraalVMLogger { + private static final Set LOGGED_MESSAGES = new HashSet<>(); + + public static void newBuild() { + synchronized (LOGGED_MESSAGES) { + LOGGED_MESSAGES.clear(); + } + } + private final Logger delegate; public static GraalVMLogger of(Logger delegate) { @@ -80,4 +91,12 @@ public void error(String s) { public void warn(String s) { delegate.warn("[native-image-plugin] {}", s); } + + public void logOnce(String message) { + synchronized (LOGGED_MESSAGES) { + if (LOGGED_MESSAGES.add(message)) { + lifecycle(message); + } + } + } } diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/GraalVMReachabilityMetadataService.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/GraalVMReachabilityMetadataService.java index d348f0b31..9a9d77d66 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/GraalVMReachabilityMetadataService.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/GraalVMReachabilityMetadataService.java @@ -41,6 +41,7 @@ package org.graalvm.buildtools.gradle.internal; import org.graalvm.buildtools.utils.FileUtils; +import org.graalvm.reachability.DirectoryConfiguration; import org.graalvm.reachability.GraalVMReachabilityMetadataRepository; import org.graalvm.reachability.Query; import org.graalvm.reachability.internal.FileSystemRepository; @@ -169,17 +170,17 @@ public void log(String groupId, String artifactId, String version, Supplier findConfigurationDirectoriesFor(Consumer queryBuilder) { - return repository.findConfigurationDirectoriesFor(queryBuilder); + public Set findConfigurationsFor(Consumer queryBuilder) { + return repository.findConfigurationsFor(queryBuilder); } /** @@ -189,11 +190,11 @@ public Set findConfigurationDirectoriesFor(Consumer queryBu * Never null. * * @param gavCoordinates the artifact GAV coordinates (group:artifact:version) - * @return a list of configuration directories + * @return a list of configurations */ @Override - public Set findConfigurationDirectoriesFor(String gavCoordinates) { - return repository.findConfigurationDirectoriesFor(gavCoordinates); + public Set findConfigurationsFor(String gavCoordinates) { + return repository.findConfigurationsFor(gavCoordinates); } /** @@ -201,10 +202,10 @@ public Set findConfigurationDirectoriesFor(String gavCoordinates) { * as an argument. * * @param modules the list of modules - * @return the set of configuration directories + * @return the set of configurations */ @Override - public Set findConfigurationDirectoriesFor(Collection modules) { - return repository.findConfigurationDirectoriesFor(modules); + public Set findConfigurationsFor(Collection modules) { + return repository.findConfigurationsFor(modules); } } 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 ea65f21b4..d30e96ca0 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 @@ -53,6 +53,8 @@ import org.gradle.process.CommandLineArgumentProvider; import java.io.File; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -64,16 +66,19 @@ public class NativeImageCommandLineProvider implements CommandLineArgumentProvid private final Provider options; private final Provider executableName; private final Provider outputDirectory; + private final Provider workingDirectory; private final Provider classpathJar; private final Provider useArgFile; public NativeImageCommandLineProvider(Provider options, Provider executableName, + Provider workingDirectory, Provider outputDirectory, Provider classpathJar, Provider useArgFile) { this.options = options; this.executableName = executableName; + this.workingDirectory = workingDirectory; this.outputDirectory = outputDirectory; this.classpathJar = classpathJar; this.useArgFile = useArgFile; @@ -142,7 +147,8 @@ public List asArguments() { } cliArgs.addAll(options.getBuildArgs().get()); if (useArgFile.getOrElse(true)) { - return NativeImageUtils.convertToArgsFile(cliArgs); + Path argFileDir = Paths.get(workingDirectory.get()); + return NativeImageUtils.convertToArgsFile(cliArgs, argFileDir, argFileDir); } return Collections.unmodifiableList(cliArgs); diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/agent/AgentConfigurationFactory.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/agent/AgentConfigurationFactory.java index 277f175af..e744bb92e 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/agent/AgentConfigurationFactory.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/agent/AgentConfigurationFactory.java @@ -59,11 +59,12 @@ import java.util.Collections; import java.util.stream.Collectors; +import static org.graalvm.buildtools.gradle.internal.ConfigurationCacheSupport.serializableTransformerOf; import static org.graalvm.buildtools.utils.SharedConstants.AGENT_OUTPUT_FOLDER; public class AgentConfigurationFactory { public static Provider getAgentConfiguration(Provider modeName, AgentOptions options) { - return modeName.map(name -> { + return modeName.map(serializableTransformerOf(name -> { AgentMode agentMode; ConfigurableFileCollection callerFilterFiles = options.getCallerFilterFiles(); ConfigurableFileCollection accessFilterFiles = options.getAccessFilterFiles(); @@ -95,7 +96,7 @@ public static Provider getAgentConfiguration(Provider getFilePaths(ConfigurableFileCollection configurableFileCollection) { 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 565c153cc..a06f2b73b 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 @@ -53,6 +53,7 @@ import org.gradle.api.file.RegularFileProperty; import org.gradle.api.model.ObjectFactory; import org.gradle.api.plugins.JavaBasePlugin; +import org.gradle.api.provider.MapProperty; import org.gradle.api.provider.Property; import org.gradle.api.provider.Provider; import org.gradle.api.provider.ProviderFactory; @@ -64,6 +65,7 @@ import org.gradle.api.tasks.Optional; import org.gradle.api.tasks.OutputDirectory; import org.gradle.api.tasks.TaskAction; +import org.gradle.api.tasks.options.Option; import org.gradle.process.ExecOperations; import javax.inject.Inject; @@ -83,6 +85,16 @@ public abstract class BuildNativeImageTask extends DefaultTask { @Nested public abstract Property getOptions(); + @Option(option = "quick-build-native", description = "Enables quick build mode") + public void overrideQuickBuild() { + getOptions().get().getQuickBuild().set(true); + } + + @Option(option = "debug-native", description = "Enables debug mode") + public void overrideDebugBuild() { + getOptions().get().getDebug().set(true); + } + @Inject protected abstract ExecOperations getExecOperations(); @@ -151,6 +163,7 @@ private List buildActualCommandLineArgs() { return new NativeImageCommandLineProvider( getOptions(), getExecutableShortName(), + getProviders().provider(() -> getWorkingDirectory().get().getAsFile().getAbsolutePath()), // Can't use getOutputDirectory().map(...) because Gradle would complain that we use // a mapped value before the task was called, when we are actually calling it... getProviders().provider(() -> getOutputDirectory().getAsFile().get().getAbsolutePath()), @@ -169,12 +182,6 @@ public void exec() { NativeImageOptions options = getOptions().get(); GraalVMLogger logger = GraalVMLogger.of(getLogger()); - String quickBuildEnv = System.getenv("GRAALVM_QUICK_BUILD"); - if (quickBuildEnv != null) { - logger.warn("Quick build environment variable is set."); - options.getQuickBuild().set(quickBuildEnv.isEmpty() || Boolean.parseBoolean(quickBuildEnv)); - } - List args = buildActualCommandLineArgs(); if (options.getVerbose().get()) { logger.lifecycle("Args are: " + args); @@ -191,6 +198,10 @@ public void exec() { File outputDir = getOutputDirectory().getAsFile().get(); if (outputDir.isDirectory() || outputDir.mkdirs()) { getExecOperations().exec(spec -> { + MapProperty environmentVariables = options.getEnvironmentVariables(); + if (environmentVariables.isPresent() && !environmentVariables.get().isEmpty()) { + spec.environment(environmentVariables.get()); + } spec.setWorkingDir(getWorkingDirectory()); if (getTestListDirectory().isPresent()) { NativeImagePlugin.TrackingDirectorySystemPropertyProvider directoryProvider = getObjects().newInstance(NativeImagePlugin.TrackingDirectorySystemPropertyProvider.class); diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/tasks/MetadataCopyTask.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/tasks/MetadataCopyTask.java index 1efc510a3..b5ec053cc 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/tasks/MetadataCopyTask.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/tasks/MetadataCopyTask.java @@ -62,6 +62,7 @@ import java.io.File; import java.io.IOException; import java.nio.file.Files; +import java.util.ArrayList; import java.util.List; import static org.graalvm.buildtools.gradle.internal.NativeImageExecutableLocator.graalvmHomeProvider; @@ -112,7 +113,7 @@ public void overrideOutputDirectories(List outputDirectories) { @TaskAction public void exec() { StringBuilder builder = new StringBuilder(); - ListProperty inputDirectories = objectFactory.listProperty(String.class); + List inputDirectories = new ArrayList<>(); for (String taskName : getInputTaskNames().get()) { File dir = AgentConfigurationFactory.getAgentOutputDirectoryForTask(layout, taskName).get().getAsFile(); @@ -128,7 +129,7 @@ public void exec() { throw new GradleException(errorString); } - ListProperty outputDirectories = objectFactory.listProperty(String.class); + List outputDirectories = new ArrayList<>(); for (String dirName : getOutputDirectories().get()) { File dir = layout.dir(providerFactory.provider(() -> new File(dirName))).get().getAsFile(); outputDirectories.add(dir.getAbsolutePath()); @@ -155,10 +156,9 @@ public void exec() { getMergeWithExisting(), objectFactory, graalvmHomeProvider(providerFactory), - inputDirectories, - outputDirectories, + () -> inputDirectories, + () -> outputDirectories, getToolchainDetection(), - execOperations, - getLogger()).execute(this); + execOperations).execute(this); } } diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/tasks/actions/CleanupAgentFilesAction.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/tasks/actions/CleanupAgentFilesAction.java index a9dd139dd..c1d0ef03d 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/tasks/actions/CleanupAgentFilesAction.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/tasks/actions/CleanupAgentFilesAction.java @@ -43,16 +43,16 @@ import org.gradle.api.Action; import org.gradle.api.Task; import org.gradle.api.file.FileSystemOperations; -import org.gradle.api.provider.Provider; import java.util.List; +import java.util.function.Supplier; public class CleanupAgentFilesAction implements Action { - private final Provider> directoriesToCleanup; + private final Supplier> directoriesToCleanup; private final FileSystemOperations fileOperations; - public CleanupAgentFilesAction(Provider> directoriesToCleanup, FileSystemOperations fileOperations) { + public CleanupAgentFilesAction(Supplier> directoriesToCleanup, FileSystemOperations fileOperations) { this.directoriesToCleanup = directoriesToCleanup; this.fileOperations = fileOperations; } diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/tasks/actions/MergeAgentFilesAction.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/tasks/actions/MergeAgentFilesAction.java index 4a4e43959..0a049a741 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/tasks/actions/MergeAgentFilesAction.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/tasks/actions/MergeAgentFilesAction.java @@ -45,7 +45,6 @@ import org.graalvm.buildtools.utils.NativeImageUtils; import org.gradle.api.Action; import org.gradle.api.Task; -import org.gradle.api.logging.Logger; import org.gradle.api.model.ObjectFactory; import org.gradle.api.provider.Property; import org.gradle.api.provider.Provider; @@ -58,6 +57,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.function.Supplier; import static org.graalvm.buildtools.gradle.internal.NativeImageExecutableLocator.findNativeImageExecutable; import static org.graalvm.buildtools.utils.NativeImageUtils.nativeImageConfigureFileName; @@ -67,23 +67,21 @@ public class MergeAgentFilesAction implements Action { private final Provider agentMode; private final Provider mergeWithOutputs; private final Provider graalvmHomeProvider; - private final Provider> inputDirs; - private final Provider> outputDirs; + private final Supplier> inputDirs; + private final Supplier> outputDirs; private final Provider disableToolchainDetection; private final Property noLauncherProperty; private final ExecOperations execOperations; - private final Logger logger; public MergeAgentFilesAction(Provider isMergingEnabled, Provider agentMode, Provider mergeWithOutputs, ObjectFactory objectFactory, Provider graalvmHomeProvider, - Provider> inputDirs, - Provider> outputDirs, + Supplier> inputDirs, + Supplier> outputDirs, Provider disableToolchainDetection, - ExecOperations execOperations, - Logger logger) { + ExecOperations execOperations) { this.isMergingEnabled = isMergingEnabled; this.agentMode = agentMode; this.mergeWithOutputs = mergeWithOutputs; @@ -92,7 +90,6 @@ public MergeAgentFilesAction(Provider isMergingEnabled, this.outputDirs = outputDirs; this.disableToolchainDetection = disableToolchainDetection; this.execOperations = execOperations; - this.logger = logger; this.noLauncherProperty = objectFactory.property(JavaLauncher.class); } @@ -103,11 +100,11 @@ private static boolean isConfigDir(String dir) { @Override public void execute(Task task) { if (isMergingEnabled.get()) { - File nativeImage = findNativeImageExecutable(noLauncherProperty, disableToolchainDetection, graalvmHomeProvider, execOperations, GraalVMLogger.of(logger)); + File nativeImage = findNativeImageExecutable(noLauncherProperty, disableToolchainDetection, graalvmHomeProvider, execOperations, GraalVMLogger.of(task.getLogger())); File workingDir = nativeImage.getParentFile(); File launcher = new File(workingDir, nativeImageConfigureFileName()); if (!launcher.exists()) { - logger.info("Installing native-image-configure"); + task.getLogger().info("Installing native-image-configure"); execOperations.exec(spec -> { spec.executable(nativeImage); spec.args("--macro:native-image-configure-launcher"); @@ -136,7 +133,7 @@ public void execute(Task task) { mergeAgentFiles(launcher, inputDirs.get(), outputDirs.get()); } } else { - logger.warn("Cannot merge agent files because native-image-configure is not installed. Please upgrade to a newer version of GraalVM."); + task.getLogger().warn("Cannot merge agent files because native-image-configure is not installed. Please upgrade to a newer version of GraalVM."); } } } diff --git a/native-gradle-plugin/src/testFixtures/groovy/org/graalvm/buildtools/gradle/fixtures/AbstractFunctionalTest.groovy b/native-gradle-plugin/src/testFixtures/groovy/org/graalvm/buildtools/gradle/fixtures/AbstractFunctionalTest.groovy index a6a4f2e8f..e580a9774 100644 --- a/native-gradle-plugin/src/testFixtures/groovy/org/graalvm/buildtools/gradle/fixtures/AbstractFunctionalTest.groovy +++ b/native-gradle-plugin/src/testFixtures/groovy/org/graalvm/buildtools/gradle/fixtures/AbstractFunctionalTest.groovy @@ -210,7 +210,8 @@ abstract class AbstractFunctionalTest extends Specification { private void assertInitScript() { initScript = file("init.gradle") - initScript << """ + if (!initScript.exists()) { + initScript << """ allprojects { repositories { maven { @@ -220,6 +221,7 @@ abstract class AbstractFunctionalTest extends Specification { } } """ + } } private class TaskExecutionGraph { diff --git a/native-maven-plugin/build-plugins/src/main/java/org/graalvm/build/maven/MavenTask.java b/native-maven-plugin/build-plugins/src/main/java/org/graalvm/build/maven/MavenTask.java index a5a8842c3..cdb97ac6e 100644 --- a/native-maven-plugin/build-plugins/src/main/java/org/graalvm/build/maven/MavenTask.java +++ b/native-maven-plugin/build-plugins/src/main/java/org/graalvm/build/maven/MavenTask.java @@ -90,12 +90,12 @@ protected void executeMaven() { spec.setClasspath(getMavenEmbedderClasspath()); spec.getMainClass().set("org.apache.maven.cli.MavenCli"); spec.systemProperty("maven.multiModuleProjectDirectory", projectdir.getAbsolutePath()); + spec.systemProperty("org.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener", "warn"); prepareSpec(spec); List arguments = new ArrayList<>(); arguments.addAll(Arrays.asList( "--errors", "-U", - "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", "--batch-mode", "--settings", settingsFile.getAbsolutePath(), "--file", pomFile.getAbsolutePath() diff --git a/native-maven-plugin/build.gradle.kts b/native-maven-plugin/build.gradle.kts index 3f7c804c5..5fdf8c481 100644 --- a/native-maven-plugin/build.gradle.kts +++ b/native-maven-plugin/build.gradle.kts @@ -63,6 +63,7 @@ dependencies { implementation(libs.utils) implementation(libs.jackson.databind) implementation(libs.jvmReachabilityMetadata) + implementation(libs.graalvm.svm) compileOnly(libs.maven.pluginApi) compileOnly(libs.maven.core) @@ -173,5 +174,5 @@ tasks { } tasks.withType().configureEach { - setConfigFile(layout.projectDirectory.dir("../config/checkstyle.xml").asFile) + configFile = layout.projectDirectory.dir("../config/checkstyle.xml").asFile } diff --git a/native-maven-plugin/reproducers/issue-144/pom.xml b/native-maven-plugin/reproducers/issue-144/pom.xml index 004761d01..0b1b3076b 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.13 - 0.9.13 + 0.9.14-SNAPSHOT + 0.9.14-SNAPSHOT example-app org.graalvm.demo.Application @@ -92,7 +92,7 @@ build-native - build + compile-no-fork package diff --git a/native-maven-plugin/src/functionalTest/groovy/org/graalvm/buildtools/maven/JavaApplicationFunctionalTest.groovy b/native-maven-plugin/src/functionalTest/groovy/org/graalvm/buildtools/maven/JavaApplicationFunctionalTest.groovy index 021b3a16f..caa8b3b7c 100644 --- a/native-maven-plugin/src/functionalTest/groovy/org/graalvm/buildtools/maven/JavaApplicationFunctionalTest.groovy +++ b/native-maven-plugin/src/functionalTest/groovy/org/graalvm/buildtools/maven/JavaApplicationFunctionalTest.groovy @@ -49,13 +49,13 @@ class JavaApplicationFunctionalTest extends AbstractGraalVMMavenFunctionalTest { when: mvn '-Pnative', '-DskipTests', '-DnativeDryRun', '-DuseArgFile=false', - '-Dclasspath=/testcp', '-Ddebug', '-Dfallback=false', '-Dverbose', '-DsharedLibrary', + '-Dclasspath=/', '-Ddebug', '-Dfallback=false', '-Dverbose', '-DsharedLibrary', '-DquickBuild', 'package' then: buildSucceeded - outputContains "native-image -cp /testcp -g --no-fallback --verbose --shared -Ob" + outputContains "native-image -cp / -g --no-fallback --verbose --shared -Ob" } def "can build and execute a native image with the Maven plugin"() { @@ -100,7 +100,7 @@ class JavaApplicationFunctionalTest extends AbstractGraalVMMavenFunctionalTest { withSample("java-application-with-custom-packaging") when: - mvn 'package', '-Dpackaging=native-image', 'exec:exec@native' + mvnDebug 'package', '-Dpackaging=native-image', 'exec:exec@native' then: buildSucceeded diff --git a/native-maven-plugin/src/functionalTest/groovy/org/graalvm/buildtools/maven/JavaApplicationWithAgentFunctionalTest.groovy b/native-maven-plugin/src/functionalTest/groovy/org/graalvm/buildtools/maven/JavaApplicationWithAgentFunctionalTest.groovy index cff916220..a0db0dcf8 100644 --- a/native-maven-plugin/src/functionalTest/groovy/org/graalvm/buildtools/maven/JavaApplicationWithAgentFunctionalTest.groovy +++ b/native-maven-plugin/src/functionalTest/groovy/org/graalvm/buildtools/maven/JavaApplicationWithAgentFunctionalTest.groovy @@ -54,7 +54,7 @@ class JavaApplicationWithAgentFunctionalTest extends AbstractGraalVMMavenFunctio when: // Run Maven in debug mode (-X) in order to capture the command line arguments // used to launch Surefire with the agent. - mvn '-X', '-Pnative', 'test', '-DskipNativeTests' + mvnDebug '-Pnative', 'test', '-DskipNativeTests' then: // Agent is used with Surefire @@ -85,7 +85,7 @@ class JavaApplicationWithAgentFunctionalTest extends AbstractGraalVMMavenFunctio when: // Run Maven in debug mode (-X) in order to capture the command line arguments // used to launch Surefire with the agent. - mvn '-X', '-Pnative', 'test' + mvnDebug '-Pnative', 'test' then: outputContains """ @@ -162,7 +162,7 @@ class JavaApplicationWithAgentFunctionalTest extends AbstractGraalVMMavenFunctio when: // Run Maven in debug mode (-X) in order to capture the command line arguments // used to launch Surefire with the agent. - mvn '-X', '-Pnative', '-DagentOptions=periodic-config', 'test' + mvnDebug '-Pnative', '-DagentOptions=periodic-config', 'test' then: outputContains """ @@ -214,7 +214,7 @@ class JavaApplicationWithAgentFunctionalTest extends AbstractGraalVMMavenFunctio withSample("java-application-with-reflection") when: - mvn '-X', '-Pnative', '-DskipTests=true', '-DskipNativeBuild=true', 'package', 'exec:exec@java-agent' + mvnDebug '-Pnative', '-DskipTests=true', '-DskipNativeBuild=true', 'package', 'exec:exec@java-agent' then: ['jni', 'proxy', 'reflect', 'resource', 'serialization'].each { name -> @@ -246,7 +246,7 @@ class JavaApplicationWithAgentFunctionalTest extends AbstractGraalVMMavenFunctio withSample("java-application-with-reflection") when: - mvn '-X', '-Pnative', '-Dagent=false', '-DskipTests=true', '-DskipNativeBuild=true', 'package', 'exec:exec@java-agent' + mvnDebug '-Pnative', '-Dagent=false', '-DskipTests=true', '-DskipNativeBuild=true', 'package', 'exec:exec@java-agent' then: outputDoesNotContain '-agentlib:native-image-agent' @@ -263,7 +263,7 @@ class JavaApplicationWithAgentFunctionalTest extends AbstractGraalVMMavenFunctio withSample("java-application-with-reflection") when: - mvn '-X', '-Pnative', '-DagentOptions=periodic-config', '-DskipTests=true', '-DskipNativeBuild=true', 'package', 'exec:exec@java-agent' + mvnDebug '-Pnative', '-DagentOptions=periodic-config', '-DskipTests=true', '-DskipNativeBuild=true', 'package', 'exec:exec@java-agent' then: ['jni', 'proxy', 'reflect', 'resource', 'serialization'].each { name -> diff --git a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeMojo.java b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeMojo.java index b8cc93b9b..3bb5acac4 100644 --- a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeMojo.java +++ b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeMojo.java @@ -58,6 +58,7 @@ import org.graalvm.buildtools.utils.FileUtils; import org.graalvm.buildtools.utils.NativeImageUtils; import org.graalvm.buildtools.utils.SharedConstants; +import org.graalvm.reachability.DirectoryConfiguration; import org.graalvm.reachability.GraalVMReachabilityMetadataRepository; import org.graalvm.reachability.internal.FileSystemRepository; @@ -82,6 +83,7 @@ import java.util.Optional; import java.util.Set; import java.util.function.Supplier; +import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -131,7 +133,7 @@ public abstract class AbstractNativeMojo extends AbstractMojo { protected final List imageClasspath; - protected final Set metadataRepositoryPaths; + protected final Set metadataRepositoryConfigurations; @Parameter(property = "debug", defaultValue = "false") protected boolean debug; @@ -192,7 +194,7 @@ public abstract class AbstractNativeMojo extends AbstractMojo { @Inject protected AbstractNativeMojo() { imageClasspath = new ArrayList<>(); - metadataRepositoryPaths = new HashSet<>(); + metadataRepositoryConfigurations = new HashSet<>(); useArgFile = SharedConstants.IS_WINDOWS; } @@ -271,15 +273,26 @@ protected List getBuildArgs() throws MojoExecutionException { } if (useArgFile) { - return NativeImageUtils.convertToArgsFile(cliArgs); + Path tmpDir = Paths.get("target", "tmp"); + return NativeImageUtils.convertToArgsFile(cliArgs, tmpDir); } return Collections.unmodifiableList(cliArgs); } - protected Path processArtifact(Artifact artifact, String artifactType) throws MojoExecutionException { + protected Path processSupportedArtifacts(Artifact artifact) throws MojoExecutionException { + return processArtifact(artifact, "jar", "test-jar", "war"); + } + + protected Path processArtifact(Artifact artifact, String... artifactTypes) throws MojoExecutionException { File artifactFile = artifact.getFile(); - if (!artifactType.equals(artifact.getType())) { - logger.warn("Ignoring non-jar type ImageClasspath Entry " + artifact); + + if (artifactFile == null) { + logger.debug("Missing artifact file for artifact " + artifact + " (type: " + artifact.getType() + ")"); + return null; + } + + if (Arrays.stream(artifactTypes).noneMatch(a -> a.equals(artifact.getType()))) { + logger.warn("Ignoring ImageClasspath Entry '" + artifact + "' with unsupported type '" + artifact.getType() + "'"); return null; } if (!artifactFile.exists()) { @@ -288,19 +301,19 @@ protected Path processArtifact(Artifact artifact, String artifactType) throws Mo } Path jarFilePath = artifactFile.toPath(); - logger.info("ImageClasspath Entry: " + artifact + " (" + jarFilePath.toUri() + ")"); + logger.debug("ImageClasspath Entry: " + artifact + " (" + jarFilePath.toUri() + ")"); warnIfWrongMetaInfLayout(jarFilePath, artifact); return jarFilePath; } protected void addArtifactToClasspath(Artifact artifact) throws MojoExecutionException { - Optional.ofNullable(processArtifact(artifact, "jar")).ifPresent(imageClasspath::add); + Optional.ofNullable(processSupportedArtifacts(artifact)).ifPresent(imageClasspath::add); } protected void warnIfWrongMetaInfLayout(Path jarFilePath, Artifact artifact) throws MojoExecutionException { if (jarFilePath.toFile().isDirectory()) { - logger.warn("Artifact `" + jarFilePath + "` is a directory."); + logger.debug("Artifact `" + jarFilePath + "` is a directory."); return; } URI jarFileURI = URI.create("jar:" + jarFilePath.toUri()); @@ -316,8 +329,9 @@ protected void warnIfWrongMetaInfLayout(Path jarFilePath, Artifact artifact) thr valid = valid && relativeSubDir.getName(0).toString().equals(artifact.getGroupId()); valid = valid && relativeSubDir.getName(1).toString().equals(artifact.getArtifactId()); if (!valid) { - String example = NATIVE_IMAGE_META_INF + "/${groupId}/${artifactId}/" + NATIVE_IMAGE_PROPERTIES_FILENAME; - logger.warn(nativeImageProperty.toUri() + " does not match recommended " + example + " layout."); + String example = NATIVE_IMAGE_META_INF + "/%s/%s/" + NATIVE_IMAGE_PROPERTIES_FILENAME; + example = String.format(example, artifact.getGroupId(), artifact.getArtifactId()); + logger.warn("Properties file at '" + nativeImageProperty.toUri() + "' does not match the recommended '" + example + "' layout."); } } } @@ -372,6 +386,7 @@ protected void populateClasspath() throws MojoExecutionException { populateApplicationClasspath(); addDependenciesToClasspath(); } + imageClasspath.removeIf(entry -> !entry.toFile().exists()); } protected String getClasspath() throws MojoExecutionException { @@ -399,7 +414,6 @@ protected void buildImage() throws MojoExecutionException { if (!outputDirectory.exists() && !outputDirectory.mkdirs()) { throw new MojoExecutionException("Failed creating output directory"); } - processBuilder.directory(outputDirectory); processBuilder.inheritIO(); String commandString = String.join(" ", processBuilder.command()); @@ -514,21 +528,18 @@ public boolean isArtifactExcludedFromMetadataRepository(Artifact dependency) { } protected void maybeAddReachabilityMetadata(List configDirs) { - if (isMetadataRepositoryEnabled() && !metadataRepositoryPaths.isEmpty()) { - String arg = metadataRepositoryPaths.stream() - .map(Path::toAbsolutePath) + if (isMetadataRepositoryEnabled() && !metadataRepositoryConfigurations.isEmpty()) { + metadataRepositoryConfigurations.stream() + .map(configuration -> configuration.getDirectory().toAbsolutePath()) .map(Path::toFile) .map(File::getAbsolutePath) - .collect(Collectors.joining(",")); - if (!arg.isEmpty()) { - configDirs.add(arg); - } + .forEach(configDirs::add); } } protected void maybeAddDependencyMetadata(Artifact dependency) { if (isMetadataRepositoryEnabled() && metadataRepository != null && !isArtifactExcludedFromMetadataRepository(dependency)) { - metadataRepositoryPaths.addAll(metadataRepository.findConfigurationDirectoriesFor(q -> { + Set configurations = metadataRepository.findConfigurationsFor(q -> { q.useLatestConfigWhenVersionIsUntested(); q.forArtifact(artifact -> { artifact.gav(String.join(":", @@ -537,7 +548,13 @@ protected void maybeAddDependencyMetadata(Artifact dependency) { dependency.getVersion())); getMetadataVersion(dependency).ifPresent(artifact::forceConfigVersion); }); - })); + }); + metadataRepositoryConfigurations.addAll(configurations); + if (configurations.stream().anyMatch(DirectoryConfiguration::isOverride)) { + buildArgs.add("--exclude-config"); + buildArgs.add(Pattern.quote(dependency.getFile().getAbsolutePath())); + buildArgs.add("^/META-INF/native-image/"); + } } } diff --git a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/DeprecatedNativeBuildMojo.java b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/DeprecatedNativeBuildMojo.java new file mode 100644 index 000000000..60d86b80e --- /dev/null +++ b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/DeprecatedNativeBuildMojo.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2020, 2022, 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; + +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.ResolutionScope; + +/** + * Mojo used to invoke native image building by attaching it to a phase. + * Deprecated in favor of compile-no-fork goal. + */ +@Deprecated +@Mojo(name = "build", defaultPhase = LifecyclePhase.PACKAGE, + requiresDependencyResolution = ResolutionScope.RUNTIME, + requiresDependencyCollection = ResolutionScope.RUNTIME) +public class DeprecatedNativeBuildMojo extends NativeCompileNoForkMojo { + + @Override + public void execute() throws MojoExecutionException { + logger.warn("'native:build' goal is deprecated. Use 'native:compile-no-fork' instead."); + super.execute(); + } + +} diff --git a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeCompileMojo.java b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeCompileMojo.java new file mode 100644 index 000000000..3cc083afb --- /dev/null +++ b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeCompileMojo.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2020, 2022, 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; + +import org.apache.maven.plugins.annotations.Execute; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.ResolutionScope; + + +/** + * This goal builds native images. + * It should be invoked from the command line as a single goal (`mvn native:compile`). + */ +@Mojo(name = "compile", defaultPhase = LifecyclePhase.PACKAGE, + requiresDependencyResolution = ResolutionScope.RUNTIME, + requiresDependencyCollection = ResolutionScope.RUNTIME) +@Execute(phase = LifecyclePhase.PACKAGE) +@SuppressWarnings("unused") +public class NativeCompileMojo extends NativeCompileNoForkMojo { +} diff --git a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeBuildMojo.java b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeCompileNoForkMojo.java similarity index 91% rename from native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeBuildMojo.java rename to native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeCompileNoForkMojo.java index 602446651..7993159ac 100644 --- a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeBuildMojo.java +++ b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeCompileNoForkMojo.java @@ -58,10 +58,15 @@ import java.util.List; import java.util.function.BiFunction; -@Mojo(name = "build", defaultPhase = LifecyclePhase.PACKAGE, + +/** + * This goal runs native builds. It functions the same as the native:compile goal, but it + * does not fork the build, so it is suitable for attaching to the build lifecycle. + */ +@Mojo(name = "compile-no-fork", defaultPhase = LifecyclePhase.PACKAGE, requiresDependencyResolution = ResolutionScope.RUNTIME, requiresDependencyCollection = ResolutionScope.RUNTIME) -public class NativeBuildMojo extends AbstractNativeMojo { +public class NativeCompileNoForkMojo extends AbstractNativeMojo { @Parameter(property = "skipNativeBuild", defaultValue = "false") private boolean skip; @@ -79,7 +84,7 @@ protected List getDependencyScopes() { @Override public void execute() throws MojoExecutionException { if (skip) { - getLog().info("Skipping native-image generation (parameter 'skipNativeBuild' is true)."); + logger.info("Skipping native-image generation (parameter 'skipNativeBuild' is true)."); return; } @@ -147,7 +152,7 @@ private void maybeSetMainClassFromPlugin(BiFunction ma mainClass = mainClassProvider.apply(pluginName, nodeNames); if (mainClass != null) { - getLog().info("Obtained main class from plugin " + pluginName + " with the following path: " + String.join(" -> ", nodeNames)); + logger.info("Obtained main class from plugin " + pluginName + " with the following path: " + String.join(" -> ", nodeNames)); } } } diff --git a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeExtension.java b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeExtension.java index 1caf2a3d0..39c5e9967 100644 --- a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeExtension.java +++ b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeExtension.java @@ -73,7 +73,7 @@ public class NativeExtension extends AbstractMavenLifecycleParticipant implement private static final String JUNIT_PLATFORM_LISTENERS_UID_TRACKING_OUTPUT_DIR = "junit.platform.listeners.uid.tracking.output.dir"; private static final String NATIVEIMAGE_IMAGECODE = "org.graalvm.nativeimage.imagecode"; - private Logger logger; + private static Logger logger; @Override public void enableLogging(Logger logger) { @@ -92,6 +92,8 @@ static String testIdsDirectory(String baseDir) { return baseDir + File.separator + "test-ids"; } + private static String graalvmJava; + static String buildAgentArgument(String baseDir, Context context, List agentOptions) { List options = new ArrayList<>(agentOptions); String effectiveOutputDir = agentOutputDirectoryFor(baseDir, context); @@ -115,6 +117,12 @@ static String agentOutputDirectoryFor(String baseDir, Context context) { @Override public void afterProjectsRead(MavenSession session) { + try { + graalvmJava = Utils.getNativeImage(logger).getParent().resolve("java").toString(); + } catch (MojoExecutionException e) { + throw new RuntimeException(e); + } + for (MavenProject project : session.getProjects()) { Build build = project.getBuild(); withPlugin(build, "native-maven-plugin", nativePlugin -> { @@ -159,12 +167,7 @@ public void afterProjectsRead(MavenSession session) { for (Xpp3Dom child : children) { commandlineArgs.addChild(child); } - Xpp3Dom executable = findOrAppend(config, "executable"); - try { - executable.setValue(Utils.getNativeImage(logger).getParent().resolve("java").toString()); - } catch (MojoExecutionException e) { - throw new RuntimeException(e); - } + findOrAppend(config, "executable").setValue(graalvmJava); } }) ); @@ -318,6 +321,7 @@ private static void configureAgentForSurefire(Plugin surefirePlugin, String agen Xpp3Dom argLine = new Xpp3Dom("argLine"); argLine.setValue(agentArgument); configuration.addChild(argLine); + findOrAppend(configuration, "jvm").setValue(graalvmJava); }); } 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 9d079f2f2..4ae827169 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 @@ -70,6 +70,7 @@ import static org.graalvm.buildtools.Utils.NATIVE_TESTS_EXE; /** + * This goal builds and runs native tests. * @author Sebastien Deleuze */ @Mojo(name = "test", defaultPhase = LifecyclePhase.TEST, threadSafe = true, diff --git a/native-maven-plugin/src/seeding-build/pom.xml b/native-maven-plugin/src/seeding-build/pom.xml index 81ad94f90..e314da800 100644 --- a/native-maven-plugin/src/seeding-build/pom.xml +++ b/native-maven-plugin/src/seeding-build/pom.xml @@ -52,6 +52,7 @@ 1.8 UTF-8 5.8.1 + 22.0.0 org.graalvm.demo.Application @@ -62,6 +63,11 @@ ${junit.jupiter.version} test + + org.graalvm.nativeimage + svm + ${graalvm.version} + @@ -80,6 +86,14 @@ ${java.version} 1.8 + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.2 + true diff --git a/native-maven-plugin/src/testFixtures/groovy/org/graalvm/buildtools/maven/AbstractGraalVMMavenFunctionalTest.groovy b/native-maven-plugin/src/testFixtures/groovy/org/graalvm/buildtools/maven/AbstractGraalVMMavenFunctionalTest.groovy index 47fa9fdd7..07798cc0b 100644 --- a/native-maven-plugin/src/testFixtures/groovy/org/graalvm/buildtools/maven/AbstractGraalVMMavenFunctionalTest.groovy +++ b/native-maven-plugin/src/testFixtures/groovy/org/graalvm/buildtools/maven/AbstractGraalVMMavenFunctionalTest.groovy @@ -139,24 +139,61 @@ abstract class AbstractGraalVMMavenFunctionalTest extends Specification { } void mvn(List args) { - mvn(args as String[]) + Map systemProperties = [ + "org.apache.http" : "off", + "org.apache.http.wire" : "off", + ].collectEntries { key, value -> + ["org.slf4j.simpleLogger.log.${key}".toString(), value] + } + mvn(args, systemProperties) } void mvn(String... args) { - System.out.println("Running copy of maven project `" + testOrigin + "` with `" + args + "`"); + mvn(args.toList()) + } + + void mvn(List args, Map systemProperties) { + System.out.println("Running copy of maven project `" + testOrigin + "` with " + args); + var resultingSystemProperties = [ + "common.repo.uri": System.getProperty("common.repo.uri"), + "seed.repo.uri": System.getProperty("seed.repo.uri"), + "maven.repo.local": testDirectory.resolve("local-repo").toFile().absolutePath + ] + resultingSystemProperties.putAll(systemProperties) + result = executor.execute( testDirectory.toFile(), - [ - "org.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener": "warn", - "common.repo.uri": System.getProperty("common.repo.uri"), - "seed.repo.uri": System.getProperty("seed.repo.uri"), - "maven.repo.local": testDirectory.resolve("local-repo").toFile().absolutePath - ], + resultingSystemProperties, [*injectedSystemProperties, *args], new File(System.getProperty("maven.settings")) ) System.out.println("Exit code is ${result.exitCode}") + + } + + void mvnDebug(String... args) { + Map systemProperties = [ + "org.apache.http" : "off", + "org.apache.http.wire" : "off", + "org.apache.maven.cli.transfer.Slf4jMavenTransferListener" : "warn", + "org.eclipse.aether.internal.impl.DefaultTransporterProvider" : "error", + "org.eclipse.aether.internal.impl.DefaultRepositoryConnectorProvider": "error", + "org.eclipse.aether.internal.impl.TrackingFileManager" : "error", + "org.eclipse.aether.internal.impl.DefaultArtifactResolver" : "error", + "org.codehaus.plexus.PlexusContainer" : "error", + "org.apache.maven.plugin.internal.DefaultPluginDependenciesResolver" : "error", + "org.apache.maven.shared.filtering.DefaultMavenFileFilter" : "error", + "org.codehaus.mojo.exec.ExecMojo" : "debug", + // This is THE logger we need for checking java execution + "org.apache.maven.lifecycle.internal.LifecycleDebugLogger" : "error" + ].collectEntries { key, value -> + ["org.slf4j.simpleLogger.log.${key}".toString(), value] + } + + ArrayList resultingArgs = args.toList() + resultingArgs.add(0, "-X") + mvn(resultingArgs, systemProperties) } boolean isDidNotCrash() { diff --git a/samples/java-application-with-custom-packaging/pom.xml b/samples/java-application-with-custom-packaging/pom.xml index b6f65cdda..181c6623b 100644 --- a/samples/java-application-with-custom-packaging/pom.xml +++ b/samples/java-application-with-custom-packaging/pom.xml @@ -41,7 +41,7 @@ --> + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.graalvm.buildtools.examples java-application-with-custom-packaging @@ -61,7 +61,7 @@ 3.3.4 org.graalvm.demo.Application netty - 0.9.13-SNAPSHOT + 0.9.14-SNAPSHOT @@ -140,7 +140,12 @@ io.micronaut.build micronaut-maven-plugin - + + org.graalvm.buildtools + native-maven-plugin + ${native.maven.plugin.version} + true + org.apache.maven.plugins maven-compiler-plugin diff --git a/samples/java-application-with-custom-tests/gradle.properties b/samples/java-application-with-custom-tests/gradle.properties index 8423039b8..d83e056c6 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.13 +native.gradle.plugin.version = 0.9.14-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 8423039b8..d83e056c6 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.13 +native.gradle.plugin.version = 0.9.14-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 8423039b8..d83e056c6 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.13 +native.gradle.plugin.version = 0.9.14-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 f9a54145d..c63d191ef 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.13 - 0.9.13 + 0.9.14-SNAPSHOT + 0.9.14-SNAPSHOT example-app org.graalvm.demo.Application @@ -131,7 +131,7 @@ build-native - build + compile-no-fork package diff --git a/samples/java-application-with-resources/gradle.properties b/samples/java-application-with-resources/gradle.properties index 8423039b8..d83e056c6 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.13 +native.gradle.plugin.version = 0.9.14-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 454776d0f..ddcb7b99b 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.13 + 0.9.14-SNAPSHOT 5.8.1 - 0.9.13 + 0.9.14-SNAPSHOT example-app org.graalvm.demo.Application @@ -100,7 +100,7 @@ build-native generateResourceConfig - build + compile-no-fork package diff --git a/samples/java-application-with-tests/gradle.properties b/samples/java-application-with-tests/gradle.properties index 8423039b8..d83e056c6 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.13 +native.gradle.plugin.version = 0.9.14-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 009a4100c..7f3a1227c 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.13 - 0.9.13 + 0.9.14-SNAPSHOT + 0.9.14-SNAPSHOT example-app org.graalvm.demo.Application @@ -95,7 +95,7 @@ build-native - build + compile-no-fork package @@ -191,7 +191,7 @@ build-native - build + compile-no-fork package diff --git a/samples/java-application/gradle.properties b/samples/java-application/gradle.properties index 8423039b8..d83e056c6 100644 --- a/samples/java-application/gradle.properties +++ b/samples/java-application/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.13 +native.gradle.plugin.version = 0.9.14-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 f53ae5981..960ee2408 100644 --- a/samples/java-application/pom.xml +++ b/samples/java-application/pom.xml @@ -51,8 +51,8 @@ 1.8 UTF-8 - 0.9.13 - 0.9.13 + 0.9.14-SNAPSHOT + 0.9.14-SNAPSHOT example-app org.graalvm.demo.Application @@ -79,7 +79,7 @@ build-native - build + compile-no-fork package @@ -126,7 +126,7 @@ build-native - build + compile-no-fork package diff --git a/samples/java-application/src/main/java/org/graalvm/demo/Application.java b/samples/java-application/src/main/java/org/graalvm/demo/Application.java index a8a992b18..c76638bf6 100644 --- a/samples/java-application/src/main/java/org/graalvm/demo/Application.java +++ b/samples/java-application/src/main/java/org/graalvm/demo/Application.java @@ -1,7 +1,9 @@ package org.graalvm.demo; public class Application { + private static final String MESSAGE = System.getenv("CUSTOM_MESSAGE"); + public static void main(String[] args) { - System.out.println("Hello, native!"); + System.out.println(MESSAGE != null ? MESSAGE : "Hello, native!"); } } diff --git a/samples/java-library/gradle.properties b/samples/java-library/gradle.properties index 8423039b8..d83e056c6 100644 --- a/samples/java-library/gradle.properties +++ b/samples/java-library/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.9.13 +native.gradle.plugin.version = 0.9.14-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 e38bb3b1e..e23e77264 100644 --- a/samples/java-library/pom.xml +++ b/samples/java-library/pom.xml @@ -51,8 +51,8 @@ 1.8 UTF-8 - 0.9.13 - 0.9.13 + 0.9.14-SNAPSHOT + 0.9.14-SNAPSHOT java-library @@ -79,7 +79,7 @@ build-native - build + compile-no-fork package diff --git a/samples/kotlin-application-with-tests/gradle.properties b/samples/kotlin-application-with-tests/gradle.properties index 8423039b8..d83e056c6 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.13 +native.gradle.plugin.version = 0.9.14-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 4d1f205d7..a1e595481 100644 --- a/samples/metadata-repo-integration/gradle.properties +++ b/samples/metadata-repo-integration/gradle.properties @@ -1,2 +1,2 @@ -native.gradle.plugin.version = 0.9.13 +native.gradle.plugin.version = 0.9.14-SNAPSHOT h2.version = 2.1.210 diff --git a/samples/metadata-repo-integration/pom.xml b/samples/metadata-repo-integration/pom.xml index 0edcff4e2..7d42540b5 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.13 - 0.9.13 + 0.9.14-SNAPSHOT + 0.9.14-SNAPSHOT 2.1.210 h2-demo org.graalvm.example.H2Example @@ -80,7 +80,7 @@ build-native - build + compile-no-fork package @@ -109,7 +109,7 @@ build-native - build + compile-no-fork package diff --git a/samples/multi-project-with-tests/gradle.properties b/samples/multi-project-with-tests/gradle.properties index 8423039b8..d83e056c6 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.13 +native.gradle.plugin.version = 0.9.14-SNAPSHOT junit.jupiter.version = 5.8.1 junit.platform.version = 1.8.1 diff --git a/samples/native-config-integration/build.gradle b/samples/native-config-integration/build.gradle index dc38d47af..685e968be 100644 --- a/samples/native-config-integration/build.gradle +++ b/samples/native-config-integration/build.gradle @@ -78,7 +78,7 @@ graalvmNative { binaries.all { verbose = true runtimeArgs.add("-DmessageClass=org.graalvm.internal.reflect.Message") - excludeConfig.put("org.graalvm.internal:library-with-reflection:1.5", ["*"]) + excludeConfig.put("org.graalvm.internal:library-with-reflection:1.5", [".*"]) excludeConfig.put(file("test.jar"), ["META-INF/*"]) } } diff --git a/samples/native-config-integration/gradle.properties b/samples/native-config-integration/gradle.properties index 8423039b8..d83e056c6 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.13 +native.gradle.plugin.version = 0.9.14-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 061d8da99..258dd5d57 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.13 - 0.9.13 + 0.9.14-SNAPSHOT + 0.9.14-SNAPSHOT example-app org.graalvm.example.Application @@ -84,7 +84,7 @@ build-native - build + compile-no-fork package @@ -128,7 +128,7 @@ build-native - build + compile-no-fork package