From 84411b1a5aa5699e94b863a00ad3a686c1d0141f Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Tue, 21 May 2024 17:06:16 +0200 Subject: [PATCH 01/36] Add exponential backoff when downloading the metadata repository Fixes #592 --- .../buildtools/utils/ExponentialBackoff.java | 128 ++++++++++++++++++ .../utils/ExponentialBackoffTest.java | 69 ++++++++++ docs/src/docs/asciidoc/index.adoc | 6 + gradle/libs.versions.toml | 2 +- .../buildtools/gradle/NativeImagePlugin.java | 6 + .../GraalVMReachabilityMetadataService.java | 24 ++-- .../gradle/internal/GradleUtils.java | 25 +++- 7 files changed, 245 insertions(+), 15 deletions(-) create mode 100644 common/utils/src/main/java/org/graalvm/buildtools/utils/ExponentialBackoff.java create mode 100644 common/utils/src/test/java/org/graalvm/buildtools/utils/ExponentialBackoffTest.java diff --git a/common/utils/src/main/java/org/graalvm/buildtools/utils/ExponentialBackoff.java b/common/utils/src/main/java/org/graalvm/buildtools/utils/ExponentialBackoff.java new file mode 100644 index 000000000..048599abc --- /dev/null +++ b/common/utils/src/main/java/org/graalvm/buildtools/utils/ExponentialBackoff.java @@ -0,0 +1,128 @@ +/* + * Copyright 2003-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.graalvm.buildtools.utils; + +import java.time.Duration; +import java.time.temporal.ChronoUnit; + +/** + * An utility class for exponential backoff of operations which + * can fail and can be retried. + */ +public class ExponentialBackoff { + private static final int DEFAULT_MAX_RETRIES = 3; + private static final Duration INITIAL_WAIT_PERIOD = Duration.of(250, ChronoUnit.MILLIS); + + private final int maxRetries; + private final Duration initialWaitPeriod; + + public ExponentialBackoff() { + this(DEFAULT_MAX_RETRIES, INITIAL_WAIT_PERIOD); + } + + private ExponentialBackoff(int maxRetries, Duration initialWaitPeriod) { + if (maxRetries < 1) { + throw new IllegalArgumentException("Max retries must be at least 1"); + } + if (initialWaitPeriod.isNegative() || initialWaitPeriod.isZero()) { + throw new IllegalArgumentException("Initial backoff wait delay must be strictly positive"); + } + this.maxRetries = maxRetries; + this.initialWaitPeriod = initialWaitPeriod; + } + + public static ExponentialBackoff get() { + return new ExponentialBackoff(); + } + + /** + * The maximum number of retries. + * + * @return an exponential backoff with the specified number of retries + */ + public ExponentialBackoff withMaxRetries(int maxRetries) { + return new ExponentialBackoff(maxRetries, initialWaitPeriod); + } + + /** + * The initial backoff duration, that is to say the time we will wait + * before the first retry (there's no wait for the initial attempt). + * + * @param duration the duration for the first retry + * @return an exponential backoff with the specified initial wait period + */ + public ExponentialBackoff withInitialWaitPeriod(Duration duration) { + return new ExponentialBackoff(maxRetries, duration); + } + + /** + * Executes an operation which returns a result. Retries a maximum number of + * times by multiplying the delay between each attempt by 2. + * @param supplier the operation to execute + * @return the result of the operation + * @param the type of the result + */ + public T supply(FailableSupplier supplier) { + int attempts = maxRetries + 1; + Duration waitPeriod = initialWaitPeriod; + Exception last = null; + while (attempts > 0) { + try { + return supplier.get(); + } catch (Exception ex) { + last = ex; + attempts--; + try { + Thread.sleep(waitPeriod.toMillis()); + waitPeriod = waitPeriod.multipliedBy(2); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RetriableOperationFailedException("Thread was interrupted", e); + } + } + } + throw new RetriableOperationFailedException("Operation failed after " + maxRetries + " retries", last); + } + + /** + * Executes an operation which doesn't return any result, until it passes, + * with this exponential backoff parameters. + * See {@link #supply(FailableSupplier)} for an operation which returns a result. + * @param operation the operation to execute. + */ + public void execute(FailableOperation operation) { + supply(() -> { + operation.run(); + return null; + }); + } + + @FunctionalInterface + public interface FailableOperation { + void run() throws Exception; + } + + @FunctionalInterface + public interface FailableSupplier { + T get() throws Exception; + } + + public static final class RetriableOperationFailedException extends RuntimeException { + public RetriableOperationFailedException(String message, Throwable cause) { + super(message, cause); + } + } +} diff --git a/common/utils/src/test/java/org/graalvm/buildtools/utils/ExponentialBackoffTest.java b/common/utils/src/test/java/org/graalvm/buildtools/utils/ExponentialBackoffTest.java new file mode 100644 index 000000000..5ccbd3dc4 --- /dev/null +++ b/common/utils/src/test/java/org/graalvm/buildtools/utils/ExponentialBackoffTest.java @@ -0,0 +1,69 @@ +package org.graalvm.buildtools.utils; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import java.time.Duration; +import java.time.temporal.ChronoUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class ExponentialBackoffTest { + @Test + @DisplayName("executed a passing operation") + void simpleExecution() { + AtomicBoolean success = new AtomicBoolean(); + ExponentialBackoff.get().execute(() -> success.set(true)); + assertTrue(success.get()); + } + + @ParameterizedTest + @ValueSource(ints = {1, 3}) + @DisplayName("retries expected amount of times") + void countRetries(int retries) { + AtomicInteger count = new AtomicInteger(); + assertThrows(ExponentialBackoff.RetriableOperationFailedException.class, () -> ExponentialBackoff.get().withMaxRetries(retries) + .execute(() -> { + count.incrementAndGet(); + throw new RuntimeException(); + })); + assertEquals(retries + 1, count.get()); + } + + @ParameterizedTest + @ValueSource(ints = {1, 3}) + @DisplayName("passes after one retry") + void passAfterRetry(int retries) { + AtomicInteger count = new AtomicInteger(); + int result = ExponentialBackoff.get().withMaxRetries(retries) + .supply(() -> { + if (count.getAndIncrement() == 0) { + throw new RuntimeException(); + } + return 200; + }); + assertEquals(2, count.get()); + assertEquals(200, result); + } + + @Test + @DisplayName("can configure initial backoff time") + void canConfigureInitialBackoffTime() { + double sd = System.currentTimeMillis(); + assertThrows(ExponentialBackoff.RetriableOperationFailedException.class, () -> ExponentialBackoff.get() + .withMaxRetries(4) + .withInitialWaitPeriod(Duration.of(1, ChronoUnit.MILLIS)) + .execute(() -> { + throw new RuntimeException(); + })); + double duration = System.currentTimeMillis() - sd; + assertTrue(duration < 100); + } + +} diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index 23f732fb1..5a1ee3912 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -19,6 +19,12 @@ If you are using alternative build systems, see < graalVMReachabilityMetadata spec.getParameters().getUri().set(repositoryExtension.getUri().map(serializableTransformerOf(configuredUri -> computeMetadataRepositoryUri(project, repositoryExtension, m -> logFallbackToDefaultUri(m, logger))))); spec.getParameters().getCacheDir().set( new File(project.getGradle().getGradleUserHomeDir(), "native-build-tools/repositories")); + spec.getParameters().getBackoffMaxRetries().convention( + GradleUtils.intProperty(project.getProviders(), "exponential.backoff.max.retries", 3) + ); + spec.getParameters().getInitialBackoffMillis().convention( + GradleUtils.intProperty(project.getProviders(), "exponential.backoff.initial.delay", 100) + ); }); } 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 e648712b8..fd0537ef2 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 @@ -40,6 +40,7 @@ */ package org.graalvm.buildtools.gradle.internal; +import org.graalvm.buildtools.utils.ExponentialBackoff; import org.graalvm.buildtools.utils.FileUtils; import org.graalvm.reachability.DirectoryConfiguration; import org.graalvm.reachability.GraalVMReachabilityMetadataRepository; @@ -66,6 +67,7 @@ import java.nio.channels.ReadableByteChannel; import java.nio.file.Files; import java.nio.file.Path; +import java.time.Duration; import java.util.Collection; import java.util.Map; import java.util.Objects; @@ -85,6 +87,10 @@ public abstract class GraalVMReachabilityMetadataService implements BuildService protected abstract FileSystemOperations getFileOperations(); public interface Params extends BuildServiceParameters { + Property getBackoffMaxRetries(); + + Property getInitialBackoffMillis(); + Property getLogLevel(); Property getUri(); @@ -124,14 +130,16 @@ private GraalVMReachabilityMetadataRepository newRepository(URI uri) throws URIS throw new RuntimeException(e); } } - - try (ReadableByteChannel readableByteChannel = Channels.newChannel(uri.toURL().openStream())) { - try (FileOutputStream fileOutputStream = new FileOutputStream(zipped)) { - fileOutputStream.getChannel().transferFrom(readableByteChannel, 0, Long.MAX_VALUE); - } - } catch (IOException e) { - throw new RuntimeException(e); - } + ExponentialBackoff.get() + .withMaxRetries(getParameters().getBackoffMaxRetries().get()) + .withInitialWaitPeriod(Duration.ofMillis(getParameters().getInitialBackoffMillis().get())) + .execute(() -> { + try (ReadableByteChannel readableByteChannel = Channels.newChannel(uri.toURL().openStream())) { + try (FileOutputStream fileOutputStream = new FileOutputStream(zipped)) { + fileOutputStream.getChannel().transferFrom(readableByteChannel, 0, Long.MAX_VALUE); + } + } + }); } return newRepositoryFromZipFile(cacheKey, zipped, logLevel); } diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/GradleUtils.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/GradleUtils.java index 6d998da56..103a5f13c 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/GradleUtils.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/GradleUtils.java @@ -48,6 +48,8 @@ import org.gradle.api.file.FileCollection; import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.plugins.JavaPluginExtension; +import org.gradle.api.provider.Provider; +import org.gradle.api.provider.ProviderFactory; import org.gradle.api.tasks.SourceSet; import org.gradle.api.tasks.SourceSetContainer; import org.gradle.util.GradleVersion; @@ -77,17 +79,28 @@ public static FileCollection transitiveProjectArtifacts(Project project, String ConfigurableFileCollection transitiveProjectArtifacts = project.getObjects().fileCollection(); transitiveProjectArtifacts.from(findMainArtifacts(project)); transitiveProjectArtifacts.from(findConfiguration(project, name) - .getIncoming() - .artifactView(view -> view.componentFilter(ProjectComponentIdentifier.class::isInstance)) - .getFiles()); + .getIncoming() + .artifactView(view -> view.componentFilter(ProjectComponentIdentifier.class::isInstance)) + .getFiles()); return transitiveProjectArtifacts; } public static FileCollection findMainArtifacts(Project project) { return findConfiguration(project, JavaPlugin.RUNTIME_ELEMENTS_CONFIGURATION_NAME) - .getOutgoing() - .getArtifacts() - .getFiles(); + .getOutgoing() + .getArtifacts() + .getFiles(); } + public static Provider intProperty(ProviderFactory providers, String propertyName, int defaultValue) { + return stringProperty(providers, propertyName) + .map(Integer::parseInt) + .orElse(defaultValue); + } + + private static Provider stringProperty(ProviderFactory providers, String propertyName) { + return providers.systemProperty(propertyName) + .orElse(providers.gradleProperty(propertyName)) + .orElse(providers.environmentVariable(propertyName.replace('.', '_').toUpperCase())); + } } From 87badeacebd9da11bbf463815258273e44d10292 Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Tue, 21 May 2024 17:52:26 +0200 Subject: [PATCH 02/36] Add exponential backoff to Maven plugin too --- docs/src/docs/asciidoc/index.adoc | 4 ++++ .../buildtools/maven/AbstractNativeMojo.java | 14 +++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index 5a1ee3912..3465c591e 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -25,6 +25,10 @@ If you are using alternative build systems, see < metadataRepositoryConfigurations; protected GraalVMReachabilityMetadataRepository metadataRepository; @@ -207,7 +215,11 @@ private Path getRepo(Path destinationRoot) { } } - return downloadMetadataRepo(destinationRoot, targetUrl); + URL finalTargetUrl = targetUrl; + return ExponentialBackoff.get() + .withMaxRetries(metadataRepositoryMaxRetries) + .withInitialWaitPeriod(Duration.ofMillis(metadataRepositoryInitialBackoffMillis)) + .supply(() -> downloadMetadataRepo(destinationRoot, finalTargetUrl)); } } From 096ea1feac6b120dcee6b6e1620958a5d1874731 Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Wed, 22 May 2024 10:36:33 +0200 Subject: [PATCH 03/36] Fix review feedback --- .../buildtools/utils/ExponentialBackoff.java | 4 ++-- .../buildtools/utils/ExponentialBackoffTest.java | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/common/utils/src/main/java/org/graalvm/buildtools/utils/ExponentialBackoff.java b/common/utils/src/main/java/org/graalvm/buildtools/utils/ExponentialBackoff.java index 048599abc..bdb4dba52 100644 --- a/common/utils/src/main/java/org/graalvm/buildtools/utils/ExponentialBackoff.java +++ b/common/utils/src/main/java/org/graalvm/buildtools/utils/ExponentialBackoff.java @@ -24,13 +24,13 @@ */ public class ExponentialBackoff { private static final int DEFAULT_MAX_RETRIES = 3; - private static final Duration INITIAL_WAIT_PERIOD = Duration.of(250, ChronoUnit.MILLIS); + private static final Duration DEFAULT_INITIAL_WAIT_PERIOD = Duration.of(250, ChronoUnit.MILLIS); private final int maxRetries; private final Duration initialWaitPeriod; public ExponentialBackoff() { - this(DEFAULT_MAX_RETRIES, INITIAL_WAIT_PERIOD); + this(DEFAULT_MAX_RETRIES, DEFAULT_INITIAL_WAIT_PERIOD); } private ExponentialBackoff(int maxRetries, Duration initialWaitPeriod) { diff --git a/common/utils/src/test/java/org/graalvm/buildtools/utils/ExponentialBackoffTest.java b/common/utils/src/test/java/org/graalvm/buildtools/utils/ExponentialBackoffTest.java index 5ccbd3dc4..ded4212e5 100644 --- a/common/utils/src/test/java/org/graalvm/buildtools/utils/ExponentialBackoffTest.java +++ b/common/utils/src/test/java/org/graalvm/buildtools/utils/ExponentialBackoffTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.graalvm.buildtools.utils; import org.junit.jupiter.api.DisplayName; From 4c616934e4b4d22191fb13879abbc4fb4499e295 Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Thu, 21 Mar 2024 14:37:42 +0100 Subject: [PATCH 04/36] Remove macro from merger init and throw better error if executable does not exist --- .../buildtools/maven/MergeAgentFilesMojo.java | 13 ++----- .../buildtools/maven/MetadataCopyMojo.java | 6 +-- .../config/AbstractMergeAgentFilesMojo.java | 38 ++++++++----------- 3 files changed, 19 insertions(+), 38 deletions(-) diff --git a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/MergeAgentFilesMojo.java b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/MergeAgentFilesMojo.java index d5b5a19f4..f752db165 100644 --- a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/MergeAgentFilesMojo.java +++ b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/MergeAgentFilesMojo.java @@ -48,11 +48,9 @@ import org.codehaus.plexus.util.FileUtils; import org.graalvm.buildtools.maven.config.AbstractMergeAgentFilesMojo; import org.graalvm.buildtools.maven.config.agent.AgentConfiguration; -import org.graalvm.buildtools.utils.NativeImageConfigurationUtils; import java.io.File; import java.io.IOException; -import java.nio.file.Path; import java.util.Arrays; import java.util.HashSet; import java.util.List; @@ -116,14 +114,12 @@ public void execute() throws MojoExecutionException { private void mergeForGivenDir(String agentOutputDirectory) throws MojoExecutionException { File baseDir = new File(agentOutputDirectory); if (baseDir.exists()) { - Path nativeImageExecutable = NativeImageConfigurationUtils.getNativeImage(logger); - tryInstallMergeExecutable(nativeImageExecutable); List sessionDirectories = sessionDirectoriesFrom(baseDir.listFiles()).collect(Collectors.toList()); if (sessionDirectories.size() == 0) { sessionDirectories = Collections.singletonList(baseDir); } - invokeMerge(mergerExecutable, sessionDirectories, baseDir); + invokeMerge(sessionDirectories, baseDir); } else { getLog().debug("Agent output directory " + baseDir + " doesn't exist. Skipping merge."); } @@ -135,11 +131,8 @@ private static Stream sessionDirectoriesFrom(File[] files) { .filter(f -> f.getName().startsWith("session-")); } - private void invokeMerge(File mergerExecutable, List inputDirectories, File outputDirectory) throws MojoExecutionException { - if (!mergerExecutable.exists()) { - getLog().warn("Cannot merge agent files because native-image-configure is not installed. Please upgrade to a newer version of GraalVM."); - return; - } + private void invokeMerge(List inputDirectories, File outputDirectory) throws MojoExecutionException { + File mergerExecutable = getMergerExecutable(); try { if (inputDirectories.isEmpty()) { getLog().warn("Skipping merging of agent files since there are no input directories."); diff --git a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/MetadataCopyMojo.java b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/MetadataCopyMojo.java index 4797fecda..267a40498 100644 --- a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/MetadataCopyMojo.java +++ b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/MetadataCopyMojo.java @@ -50,12 +50,10 @@ import org.graalvm.buildtools.maven.config.AbstractMergeAgentFilesMojo; import org.graalvm.buildtools.maven.config.agent.AgentConfiguration; import org.graalvm.buildtools.maven.config.agent.MetadataCopyConfiguration; -import org.graalvm.buildtools.utils.NativeImageConfigurationUtils; import java.io.File; import java.io.IOException; import java.nio.file.Files; -import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; import java.util.Collections; @@ -113,8 +111,6 @@ public void execute() throws MojoExecutionException { } } - Path nativeImageExecutable = NativeImageConfigurationUtils.getNativeImage(logger); - tryInstallMergeExecutable(nativeImageExecutable); executeCopy(buildDirectory, destinationDir); getLog().info("Metadata copy process finished."); } @@ -155,7 +151,7 @@ private void executeCopy(String buildDirectory, String destinationDir) throws Mo logger.info("Copying files from: " + sourceDirsInfo); List nativeImageConfigureOptions = new StandardAgentMode().getNativeImageConfigureOptions(sourceDirectories, Collections.singletonList(destinationDir)); - nativeImageConfigureOptions.add(0, mergerExecutable.getAbsolutePath()); + nativeImageConfigureOptions.add(0, getMergerExecutable().getAbsolutePath()); ProcessBuilder processBuilder = new ProcessBuilder(nativeImageConfigureOptions); try { diff --git a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/config/AbstractMergeAgentFilesMojo.java b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/config/AbstractMergeAgentFilesMojo.java index 0e5b8b440..870f2dfe9 100644 --- a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/config/AbstractMergeAgentFilesMojo.java +++ b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/config/AbstractMergeAgentFilesMojo.java @@ -42,12 +42,12 @@ package org.graalvm.buildtools.maven.config; import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.annotations.Component; import org.codehaus.plexus.logging.Logger; -import org.graalvm.buildtools.utils.NativeImageUtils; +import org.graalvm.buildtools.utils.NativeImageConfigurationUtils; import java.io.File; -import java.io.IOException; import java.nio.file.Path; import static org.graalvm.buildtools.utils.NativeImageUtils.nativeImageConfigureFileName; @@ -58,32 +58,24 @@ public abstract class AbstractMergeAgentFilesMojo extends AbstractMojo { @Component protected Logger logger; - protected File mergerExecutable; + private File mergerExecutable; - protected void tryInstallMergeExecutable(Path nativeImageExecutablePath) { - if (mergerExecutable != null && mergerExecutable.exists()) { - return; + public File getMergerExecutable() throws MojoExecutionException { + if (mergerExecutable == null) { + initializeMergerExecutable(); } - File nativeImageExecutable = nativeImageExecutablePath.toAbsolutePath().toFile(); + return mergerExecutable; + } + + private void initializeMergerExecutable() throws MojoExecutionException { + Path nativeImage = NativeImageConfigurationUtils.getNativeImage(logger); + File nativeImageExecutable = nativeImage.toAbsolutePath().toFile(); File mergerExecutable = new File(nativeImageExecutable.getParentFile(), nativeImageConfigureFileName()); if (!mergerExecutable.exists()) { - getLog().info("Installing native image merger to " + mergerExecutable); - ProcessBuilder processBuilder = new ProcessBuilder(nativeImageExecutable.toString()); - processBuilder.command().add("--macro:native-image-configure-launcher"); - processBuilder.directory(mergerExecutable.getParentFile()); - processBuilder.inheritIO(); - - try { - Process installProcess = processBuilder.start(); - if (installProcess.waitFor() != 0) { - getLog().warn("Installation of native image merging tool failed"); - } - NativeImageUtils.maybeCreateConfigureUtilSymlink(mergerExecutable, nativeImageExecutablePath); - } catch (IOException | InterruptedException e) { - // ignore since we will handle that if the installer doesn't exist later - } - + throw new MojoExecutionException("'" + nativeImageConfigureFileName() + "' tool was not found in your " + nativeImage + "." + + "This probably means that the JDK at '" + nativeImage + "' is not a GraalVM distribution." + ); } this.mergerExecutable = mergerExecutable; From 12aa7c89067ad945a10a84b3fb62d98eaa4e068d Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Wed, 10 Apr 2024 12:52:09 +0200 Subject: [PATCH 05/36] Extract Native Image configure file name into variable --- .../buildtools/maven/config/AbstractMergeAgentFilesMojo.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/config/AbstractMergeAgentFilesMojo.java b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/config/AbstractMergeAgentFilesMojo.java index 870f2dfe9..d4d3321c0 100644 --- a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/config/AbstractMergeAgentFilesMojo.java +++ b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/config/AbstractMergeAgentFilesMojo.java @@ -71,9 +71,10 @@ public File getMergerExecutable() throws MojoExecutionException { private void initializeMergerExecutable() throws MojoExecutionException { Path nativeImage = NativeImageConfigurationUtils.getNativeImage(logger); File nativeImageExecutable = nativeImage.toAbsolutePath().toFile(); - File mergerExecutable = new File(nativeImageExecutable.getParentFile(), nativeImageConfigureFileName()); + String configureFileName = nativeImageConfigureFileName(); + File mergerExecutable = new File(nativeImageExecutable.getParentFile(), configureFileName); if (!mergerExecutable.exists()) { - throw new MojoExecutionException("'" + nativeImageConfigureFileName() + "' tool was not found in your " + nativeImage + "." + + throw new MojoExecutionException("'" + configureFileName + "' tool was not found in your " + nativeImage + "." + "This probably means that the JDK at '" + nativeImage + "' is not a GraalVM distribution." ); } From 67dcd82744b4bec39e395aa50de1e6c898481edf Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Wed, 10 Apr 2024 12:55:22 +0200 Subject: [PATCH 06/36] Change error message when mergerExecutable does not exist --- .../maven/config/AbstractMergeAgentFilesMojo.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/config/AbstractMergeAgentFilesMojo.java b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/config/AbstractMergeAgentFilesMojo.java index d4d3321c0..4b92ce2c8 100644 --- a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/config/AbstractMergeAgentFilesMojo.java +++ b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/config/AbstractMergeAgentFilesMojo.java @@ -71,11 +71,11 @@ public File getMergerExecutable() throws MojoExecutionException { private void initializeMergerExecutable() throws MojoExecutionException { Path nativeImage = NativeImageConfigurationUtils.getNativeImage(logger); File nativeImageExecutable = nativeImage.toAbsolutePath().toFile(); - String configureFileName = nativeImageConfigureFileName(); - File mergerExecutable = new File(nativeImageExecutable.getParentFile(), configureFileName); + String nativeImageConfigureFileName = nativeImageConfigureFileName(); + File mergerExecutable = new File(nativeImageExecutable.getParentFile(), nativeImageConfigureFileName); if (!mergerExecutable.exists()) { - throw new MojoExecutionException("'" + configureFileName + "' tool was not found in your " + nativeImage + "." + - "This probably means that the JDK at '" + nativeImage + "' is not a GraalVM distribution." + throw new MojoExecutionException("'" + nativeImageConfigureFileName + "' tool was not found in the GraalVM JDK at '" + nativeImageExecutable.getParentFile().getParentFile() + "'." + + "This probably means that you are using a GraalVM distribution that is not fully supported by the Native Build Tools." ); } From fdb7c00347dd76ac9845f93e58c4eb60f938a634 Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Wed, 22 May 2024 10:06:05 +0200 Subject: [PATCH 07/36] Improve error messages --- .../buildtools/maven/config/AbstractMergeAgentFilesMojo.java | 5 +++-- .../buildtools/utils/NativeImageConfigurationUtils.java | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/config/AbstractMergeAgentFilesMojo.java b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/config/AbstractMergeAgentFilesMojo.java index 4b92ce2c8..3323845ea 100644 --- a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/config/AbstractMergeAgentFilesMojo.java +++ b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/config/AbstractMergeAgentFilesMojo.java @@ -74,8 +74,9 @@ private void initializeMergerExecutable() throws MojoExecutionException { String nativeImageConfigureFileName = nativeImageConfigureFileName(); File mergerExecutable = new File(nativeImageExecutable.getParentFile(), nativeImageConfigureFileName); if (!mergerExecutable.exists()) { - throw new MojoExecutionException("'" + nativeImageConfigureFileName + "' tool was not found in the GraalVM JDK at '" + nativeImageExecutable.getParentFile().getParentFile() + "'." + - "This probably means that you are using a GraalVM distribution that is not fully supported by the Native Build Tools." + throw new MojoExecutionException("The '" + nativeImageConfigureFileName + "' tool was not found in the GraalVM JDK at '" + nativeImageExecutable.getParentFile().getParentFile() + "'." + + "This probably means that you are using a GraalVM distribution that is not fully supported by the Native Build Tools. " + + "Please try again, for example, with Oracle GraalVM or GraalVM Community Edition." ); } diff --git a/native-maven-plugin/src/main/java/org/graalvm/buildtools/utils/NativeImageConfigurationUtils.java b/native-maven-plugin/src/main/java/org/graalvm/buildtools/utils/NativeImageConfigurationUtils.java index 2dadfedc3..f1e01f24c 100644 --- a/native-maven-plugin/src/main/java/org/graalvm/buildtools/utils/NativeImageConfigurationUtils.java +++ b/native-maven-plugin/src/main/java/org/graalvm/buildtools/utils/NativeImageConfigurationUtils.java @@ -128,8 +128,8 @@ public static Path getNativeImage(Logger logger) throws MojoExecutionException { } if (nativeImage == null) { - throw new RuntimeException("GraalVM native-image is missing on your system. " + System.lineSeparator() + - "Make sure that GRAALVM_HOME environment variable is present."); + throw new RuntimeException("The 'native-image' tool was not found on your system. " + System.lineSeparator() + + "Make sure that the JAVA_HOME or GRAALVM_HOME environment variables point to a GraalVM JDK, or that 'native-image' is on the system path."); } nativeImageExeCache = nativeImage; From 6a419c60c35dc3b9017f0f54c06868e478b64bfd Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Wed, 22 May 2024 10:18:49 +0200 Subject: [PATCH 08/36] Add changelog entry --- docs/src/docs/asciidoc/index.adoc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index 3465c591e..f8d70c9ec 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -21,6 +21,8 @@ If you are using alternative build systems, see < Date: Thu, 23 May 2024 11:17:59 +0200 Subject: [PATCH 09/36] Remove redudant newline --- .../graalvm/buildtools/utils/NativeImageConfigurationUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/native-maven-plugin/src/main/java/org/graalvm/buildtools/utils/NativeImageConfigurationUtils.java b/native-maven-plugin/src/main/java/org/graalvm/buildtools/utils/NativeImageConfigurationUtils.java index f1e01f24c..e3401033b 100644 --- a/native-maven-plugin/src/main/java/org/graalvm/buildtools/utils/NativeImageConfigurationUtils.java +++ b/native-maven-plugin/src/main/java/org/graalvm/buildtools/utils/NativeImageConfigurationUtils.java @@ -128,7 +128,7 @@ public static Path getNativeImage(Logger logger) throws MojoExecutionException { } if (nativeImage == null) { - throw new RuntimeException("The 'native-image' tool was not found on your system. " + System.lineSeparator() + + throw new RuntimeException("The 'native-image' tool was not found on your system. " + "Make sure that the JAVA_HOME or GRAALVM_HOME environment variables point to a GraalVM JDK, or that 'native-image' is on the system path."); } From 34c9d26336ad771b5d6d9781d62343b69d51e20c Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Fri, 17 May 2024 18:30:56 +0200 Subject: [PATCH 10/36] Bump repo version to next snapshot and update samples --- native-maven-plugin/reproducers/issue-144/pom.xml | 4 ++-- samples/java-application-with-custom-packaging/pom.xml | 2 +- samples/java-application-with-custom-tests/gradle.properties | 2 +- .../java-application-with-extra-sourceset/gradle.properties | 2 +- samples/java-application-with-reflection/gradle.properties | 2 +- samples/java-application-with-reflection/pom.xml | 4 ++-- samples/java-application-with-resources/gradle.properties | 2 +- samples/java-application-with-resources/pom.xml | 4 ++-- samples/java-application-with-tests/gradle.properties | 2 +- samples/java-application-with-tests/pom.xml | 4 ++-- samples/java-application/gradle.properties | 2 +- samples/java-application/pom.xml | 4 ++-- samples/java-library/gradle.properties | 2 +- samples/java-library/pom.xml | 4 ++-- samples/kotlin-application-with-tests/gradle.properties | 2 +- samples/metadata-repo-integration/gradle.properties | 2 +- samples/metadata-repo-integration/pom.xml | 4 ++-- samples/multi-project-with-tests/gradle.properties | 2 +- samples/multi-project-with-tests/pom.xml | 4 ++-- samples/native-config-integration/gradle.properties | 2 +- samples/native-config-integration/pom.xml | 4 ++-- 21 files changed, 30 insertions(+), 30 deletions(-) diff --git a/native-maven-plugin/reproducers/issue-144/pom.xml b/native-maven-plugin/reproducers/issue-144/pom.xml index 0f07a3185..770ad3a54 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.10.2 - 0.10.2 + 0.10.3-SNAPSHOT + 0.10.3-SNAPSHOT example-app org.graalvm.demo.Application diff --git a/samples/java-application-with-custom-packaging/pom.xml b/samples/java-application-with-custom-packaging/pom.xml index 80cf8b6a3..088de9e27 100644 --- a/samples/java-application-with-custom-packaging/pom.xml +++ b/samples/java-application-with-custom-packaging/pom.xml @@ -61,7 +61,7 @@ 3.3.4 org.graalvm.demo.Application netty - 0.10.2 + 0.10.3-SNAPSHOT diff --git a/samples/java-application-with-custom-tests/gradle.properties b/samples/java-application-with-custom-tests/gradle.properties index d2b31cecc..91743431e 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.10.2 +native.gradle.plugin.version = 0.10.3-SNAPSHOT junit.jupiter.version = 5.10.0 junit.platform.version = 1.10.0 diff --git a/samples/java-application-with-extra-sourceset/gradle.properties b/samples/java-application-with-extra-sourceset/gradle.properties index d2b31cecc..91743431e 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.10.2 +native.gradle.plugin.version = 0.10.3-SNAPSHOT junit.jupiter.version = 5.10.0 junit.platform.version = 1.10.0 diff --git a/samples/java-application-with-reflection/gradle.properties b/samples/java-application-with-reflection/gradle.properties index d2b31cecc..91743431e 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.10.2 +native.gradle.plugin.version = 0.10.3-SNAPSHOT junit.jupiter.version = 5.10.0 junit.platform.version = 1.10.0 diff --git a/samples/java-application-with-reflection/pom.xml b/samples/java-application-with-reflection/pom.xml index 10dd0a3ab..80d08c102 100644 --- a/samples/java-application-with-reflection/pom.xml +++ b/samples/java-application-with-reflection/pom.xml @@ -52,8 +52,8 @@ 1.8 UTF-8 5.10.0 - 0.10.2 - 0.10.2 + 0.10.3-SNAPSHOT + 0.10.3-SNAPSHOT example-app org.graalvm.demo.Application diff --git a/samples/java-application-with-resources/gradle.properties b/samples/java-application-with-resources/gradle.properties index d2b31cecc..91743431e 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.10.2 +native.gradle.plugin.version = 0.10.3-SNAPSHOT junit.jupiter.version = 5.10.0 junit.platform.version = 1.10.0 diff --git a/samples/java-application-with-resources/pom.xml b/samples/java-application-with-resources/pom.xml index dbfe6d0f7..7d2b63625 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.10.2 + 0.10.3-SNAPSHOT 5.10.0 - 0.10.2 + 0.10.3-SNAPSHOT example-app org.graalvm.demo.Application diff --git a/samples/java-application-with-tests/gradle.properties b/samples/java-application-with-tests/gradle.properties index d2b31cecc..91743431e 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.10.2 +native.gradle.plugin.version = 0.10.3-SNAPSHOT junit.jupiter.version = 5.10.0 junit.platform.version = 1.10.0 diff --git a/samples/java-application-with-tests/pom.xml b/samples/java-application-with-tests/pom.xml index b30e970db..ef0d75d8c 100644 --- a/samples/java-application-with-tests/pom.xml +++ b/samples/java-application-with-tests/pom.xml @@ -52,8 +52,8 @@ 1.8 UTF-8 5.10.0 - 0.10.2 - 0.10.2 + 0.10.3-SNAPSHOT + 0.10.3-SNAPSHOT example-app org.graalvm.demo.Application diff --git a/samples/java-application/gradle.properties b/samples/java-application/gradle.properties index d2b31cecc..91743431e 100644 --- a/samples/java-application/gradle.properties +++ b/samples/java-application/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.10.2 +native.gradle.plugin.version = 0.10.3-SNAPSHOT junit.jupiter.version = 5.10.0 junit.platform.version = 1.10.0 diff --git a/samples/java-application/pom.xml b/samples/java-application/pom.xml index 0fbb2bc5a..9fda870d9 100644 --- a/samples/java-application/pom.xml +++ b/samples/java-application/pom.xml @@ -51,8 +51,8 @@ 1.8 UTF-8 - 0.10.2 - 0.10.2 + 0.10.3-SNAPSHOT + 0.10.3-SNAPSHOT example-app org.graalvm.demo.Application diff --git a/samples/java-library/gradle.properties b/samples/java-library/gradle.properties index d2b31cecc..91743431e 100644 --- a/samples/java-library/gradle.properties +++ b/samples/java-library/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.10.2 +native.gradle.plugin.version = 0.10.3-SNAPSHOT junit.jupiter.version = 5.10.0 junit.platform.version = 1.10.0 diff --git a/samples/java-library/pom.xml b/samples/java-library/pom.xml index 52659ff60..c763a9be0 100644 --- a/samples/java-library/pom.xml +++ b/samples/java-library/pom.xml @@ -51,8 +51,8 @@ 1.8 UTF-8 - 0.10.2 - 0.10.2 + 0.10.3-SNAPSHOT + 0.10.3-SNAPSHOT java-library diff --git a/samples/kotlin-application-with-tests/gradle.properties b/samples/kotlin-application-with-tests/gradle.properties index d2b31cecc..91743431e 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.10.2 +native.gradle.plugin.version = 0.10.3-SNAPSHOT junit.jupiter.version = 5.10.0 junit.platform.version = 1.10.0 diff --git a/samples/metadata-repo-integration/gradle.properties b/samples/metadata-repo-integration/gradle.properties index 76fe24d37..7bbf5b7a8 100644 --- a/samples/metadata-repo-integration/gradle.properties +++ b/samples/metadata-repo-integration/gradle.properties @@ -1,4 +1,4 @@ -native.gradle.plugin.version = 0.10.2 +native.gradle.plugin.version = 0.10.3-SNAPSHOT h2.version = 2.2.220 netty.version = 4.1.80.Final logback.version = 1.4.4 diff --git a/samples/metadata-repo-integration/pom.xml b/samples/metadata-repo-integration/pom.xml index 30f584467..c17655d2e 100644 --- a/samples/metadata-repo-integration/pom.xml +++ b/samples/metadata-repo-integration/pom.xml @@ -51,8 +51,8 @@ 1.8 UTF-8 - 0.10.2 - 0.10.2 + 0.10.3-SNAPSHOT + 0.10.3-SNAPSHOT 2.2.220 4.1.80.Final 1.4.12 diff --git a/samples/multi-project-with-tests/gradle.properties b/samples/multi-project-with-tests/gradle.properties index d2b31cecc..91743431e 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.10.2 +native.gradle.plugin.version = 0.10.3-SNAPSHOT junit.jupiter.version = 5.10.0 junit.platform.version = 1.10.0 diff --git a/samples/multi-project-with-tests/pom.xml b/samples/multi-project-with-tests/pom.xml index b8deacacc..c0cec21c7 100644 --- a/samples/multi-project-with-tests/pom.xml +++ b/samples/multi-project-with-tests/pom.xml @@ -58,8 +58,8 @@ 1.8 UTF-8 5.10.0 - 0.10.2 - 0.10.2 + 0.10.3-SNAPSHOT + 0.10.3-SNAPSHOT example-app org.graalvm.demo.Application diff --git a/samples/native-config-integration/gradle.properties b/samples/native-config-integration/gradle.properties index d2b31cecc..91743431e 100644 --- a/samples/native-config-integration/gradle.properties +++ b/samples/native-config-integration/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.10.2 +native.gradle.plugin.version = 0.10.3-SNAPSHOT junit.jupiter.version = 5.10.0 junit.platform.version = 1.10.0 diff --git a/samples/native-config-integration/pom.xml b/samples/native-config-integration/pom.xml index 0958156e0..48cb945e0 100644 --- a/samples/native-config-integration/pom.xml +++ b/samples/native-config-integration/pom.xml @@ -51,8 +51,8 @@ 1.8 UTF-8 - 0.10.2 - 0.10.2 + 0.10.3-SNAPSHOT + 0.10.3-SNAPSHOT example-app org.graalvm.example.Application From 84a9d72555376f7570b80fdcb45e6485310089f7 Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Mon, 27 May 2024 11:51:54 +0200 Subject: [PATCH 11/36] Add missing documentation for 0.10.2 release --- docs/src/docs/asciidoc/index.adoc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index f8d70c9ec..d14e45e0b 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -31,6 +31,22 @@ If you are using alternative build systems, see < Date: Tue, 9 Jul 2024 01:11:28 +0100 Subject: [PATCH 12/36] fix buildArgs with whitespaces in path --- .../maven/AbstractNativeImageMojo.java | 26 +++++++++++++++++-- .../AbstractGraalVMMavenFunctionalTest.groovy | 3 +-- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java index fa5e563bd..29d1d57b8 100644 --- a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java +++ b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java @@ -240,10 +240,32 @@ protected List getBuildArgs() throws MojoExecutionException { .collect(Collectors.joining(",")) ); } - + logger.debug("ARGS:" + buildArgs); if (buildArgs != null && !buildArgs.isEmpty()) { for (String buildArg : buildArgs) { - cliArgs.addAll(Arrays.asList(buildArg.split("\\s+"))); + if(buildArg.startsWith("\\Q") || + buildArg.startsWith("--H:ConfigurationFileDirectories")) { + continue; + } + String[] args = buildArg.split("\\s+"); + int i=0; + while(i < args.length) { + String a =args[i]; + if (a.startsWith(""+System.getProperty("user.home").charAt(0))) { + StringBuilder path = new StringBuilder(a); + i++; + String tempArg = args[i].trim().toLowerCase(); + while(i < args.length && tempArg.charAt(0) <= 'z' && + tempArg.charAt(0) >= 'a') { + path.append(" ").append(args[i]); + i++; + } + cliArgs.add(path.toString()); + } else { + cliArgs.add(a); + i++; + } + } } } 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 00c593bc6..a030091db 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 @@ -54,8 +54,7 @@ import java.nio.file.Path import java.nio.file.StandardCopyOption abstract class AbstractGraalVMMavenFunctionalTest extends Specification { - @TempDir - Path testDirectory + Path testDirectory = Path.of("C:\\Users\\Lahoucine EL ADDALI\\Desktop\\tests"); Path testOrigin; From 311c8ad59ed0ab7cae53e36145146505041cd2ed Mon Sep 17 00:00:00 2001 From: Lahoucine EL ADDALI Date: Tue, 9 Jul 2024 01:12:50 +0100 Subject: [PATCH 13/36] revert to use tempdir for testing --- .../buildtools/maven/AbstractGraalVMMavenFunctionalTest.groovy | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 a030091db..00c593bc6 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 @@ -54,7 +54,8 @@ import java.nio.file.Path import java.nio.file.StandardCopyOption abstract class AbstractGraalVMMavenFunctionalTest extends Specification { - Path testDirectory = Path.of("C:\\Users\\Lahoucine EL ADDALI\\Desktop\\tests"); + @TempDir + Path testDirectory Path testOrigin; From 19d8fde860c13d1a5167808c5c6ccc9359e387b8 Mon Sep 17 00:00:00 2001 From: Lahoucine EL ADDALI Date: Tue, 9 Jul 2024 10:35:30 +0100 Subject: [PATCH 14/36] fix failing tests --- .../graalvm/buildtools/maven/AbstractNativeImageMojo.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java index 29d1d57b8..766cecd51 100644 --- a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java +++ b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java @@ -254,9 +254,8 @@ protected List getBuildArgs() throws MojoExecutionException { if (a.startsWith(""+System.getProperty("user.home").charAt(0))) { StringBuilder path = new StringBuilder(a); i++; - String tempArg = args[i].trim().toLowerCase(); - while(i < args.length && tempArg.charAt(0) <= 'z' && - tempArg.charAt(0) >= 'a') { + while( i< args.length && args[i].toLowerCase().charAt(0) <= 'z' && + args[i].toLowerCase().charAt(0) >= 'a') { path.append(" ").append(args[i]); i++; } From 4b8987b8ab3524e0c91d741004f4c209f1603f53 Mon Sep 17 00:00:00 2001 From: Lahoucine EL ADDALI Date: Tue, 9 Jul 2024 10:36:35 +0100 Subject: [PATCH 15/36] refactor --- .../org/graalvm/buildtools/maven/AbstractNativeImageMojo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java index 766cecd51..888ec2569 100644 --- a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java +++ b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java @@ -240,7 +240,7 @@ protected List getBuildArgs() throws MojoExecutionException { .collect(Collectors.joining(",")) ); } - logger.debug("ARGS:" + buildArgs); + if (buildArgs != null && !buildArgs.isEmpty()) { for (String buildArg : buildArgs) { if(buildArg.startsWith("\\Q") || From 49b26ad61f1831eb87689373f302527d71b70085 Mon Sep 17 00:00:00 2001 From: Lahoucine EL ADDALI Date: Wed, 10 Jul 2024 12:27:00 +0100 Subject: [PATCH 16/36] fix add missing build args --- .../org/graalvm/buildtools/maven/AbstractNativeImageMojo.java | 1 + 1 file changed, 1 insertion(+) diff --git a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java index 888ec2569..9404bdba0 100644 --- a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java +++ b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java @@ -245,6 +245,7 @@ protected List getBuildArgs() throws MojoExecutionException { for (String buildArg : buildArgs) { if(buildArg.startsWith("\\Q") || buildArg.startsWith("--H:ConfigurationFileDirectories")) { + cliArgs.add(buildArg); continue; } String[] args = buildArg.split("\\s+"); From 988cfadae7c7cd3ba75c9ed038ce7fd074d938cb Mon Sep 17 00:00:00 2001 From: Lahoucine EL ADDALI Date: Tue, 23 Jul 2024 23:32:29 +0100 Subject: [PATCH 17/36] add workflow for whitespace home folders --- .../actions/prepare-environment/action.yml | 1 + .../workflows/test-native-maven-plugin.yml | 27 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/.github/actions/prepare-environment/action.yml b/.github/actions/prepare-environment/action.yml index e23595052..18627d6a4 100644 --- a/.github/actions/prepare-environment/action.yml +++ b/.github/actions/prepare-environment/action.yml @@ -52,3 +52,4 @@ runs: git config --global user.name 'graalvm bot' git config --global user.email 'graalvmbot@users.noreply.github.com' echo "org.ajoberstar.grgit.auth.command.allow=true" >> gradle.properties + mkdir -p ~/test with whitespaces/.m2 diff --git a/.github/workflows/test-native-maven-plugin.yml b/.github/workflows/test-native-maven-plugin.yml index 3e13d60dd..874fcb9a1 100644 --- a/.github/workflows/test-native-maven-plugin.yml +++ b/.github/workflows/test-native-maven-plugin.yml @@ -68,3 +68,30 @@ jobs: with: name: maven-functional-tests-results-${{ matrix.os }} path: native-maven-plugin/build/reports/tests/ + + test-native-maven-plugin-with-whitespaces: + name: "🧪 Maven: ${{ matrix.test }} on ${{ matrix.os }}" + runs-on: ${{ matrix.os }} + timeout-minutes: 60 + needs: populate-matrix + strategy: + fail-fast: false + matrix: ${{fromJson(needs.populate-matrix.outputs.matrix)}} + steps: + - name: "☁️ Checkout repository" + uses: actions/checkout@v4 + - name: "🔧 Prepare environment" + uses: ./.github/actions/prepare-environment + with: + java-version: ${{ matrix.java-version }} + github-token: ${{ secrets.GITHUB_TOKEN }} + - name: "Set .m2 location to a folder with whitespaces" + run: echo "MAVEN_OPTS=-Dmaven.repo.local=~/test with whitespaces/.m2" >> $GITHUB_ENV + - name: "❓ Check and test the plugin" + run: ./gradlew :native-maven-plugin:functionalTest --no-daemon --fail-fast --tests ${{ matrix.test }} + - name: "📜 Upload unit test results" + if: always() + uses: actions/upload-artifact@v3 + with: + name: maven-functional-tests-results-${{ matrix.os }} + path: native-maven-plugin/build/reports/tests/ From c87de637419173f095a11ddd2a6e1586f699dc35 Mon Sep 17 00:00:00 2001 From: Lahoucine EL ADDALI Date: Sun, 28 Jul 2024 15:01:48 +0100 Subject: [PATCH 18/36] change testing dir and use repo with whitespaces --- .../actions/prepare-environment/action.yml | 1 - .../workflows/test-native-maven-plugin.yml | 27 ----------------- .../maven/AbstractNativeImageMojo.java | 4 +-- .../AbstractGraalVMMavenFunctionalTest.groovy | 29 +++++++++++++++++-- 4 files changed, 29 insertions(+), 32 deletions(-) diff --git a/.github/actions/prepare-environment/action.yml b/.github/actions/prepare-environment/action.yml index 18627d6a4..e23595052 100644 --- a/.github/actions/prepare-environment/action.yml +++ b/.github/actions/prepare-environment/action.yml @@ -52,4 +52,3 @@ runs: git config --global user.name 'graalvm bot' git config --global user.email 'graalvmbot@users.noreply.github.com' echo "org.ajoberstar.grgit.auth.command.allow=true" >> gradle.properties - mkdir -p ~/test with whitespaces/.m2 diff --git a/.github/workflows/test-native-maven-plugin.yml b/.github/workflows/test-native-maven-plugin.yml index 874fcb9a1..3e13d60dd 100644 --- a/.github/workflows/test-native-maven-plugin.yml +++ b/.github/workflows/test-native-maven-plugin.yml @@ -68,30 +68,3 @@ jobs: with: name: maven-functional-tests-results-${{ matrix.os }} path: native-maven-plugin/build/reports/tests/ - - test-native-maven-plugin-with-whitespaces: - name: "🧪 Maven: ${{ matrix.test }} on ${{ matrix.os }}" - runs-on: ${{ matrix.os }} - timeout-minutes: 60 - needs: populate-matrix - strategy: - fail-fast: false - matrix: ${{fromJson(needs.populate-matrix.outputs.matrix)}} - steps: - - name: "☁️ Checkout repository" - uses: actions/checkout@v4 - - name: "🔧 Prepare environment" - uses: ./.github/actions/prepare-environment - with: - java-version: ${{ matrix.java-version }} - github-token: ${{ secrets.GITHUB_TOKEN }} - - name: "Set .m2 location to a folder with whitespaces" - run: echo "MAVEN_OPTS=-Dmaven.repo.local=~/test with whitespaces/.m2" >> $GITHUB_ENV - - name: "❓ Check and test the plugin" - run: ./gradlew :native-maven-plugin:functionalTest --no-daemon --fail-fast --tests ${{ matrix.test }} - - name: "📜 Upload unit test results" - if: always() - uses: actions/upload-artifact@v3 - with: - name: maven-functional-tests-results-${{ matrix.os }} - path: native-maven-plugin/build/reports/tests/ diff --git a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java index 9404bdba0..c05e2f37e 100644 --- a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java +++ b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java @@ -244,7 +244,7 @@ protected List getBuildArgs() throws MojoExecutionException { if (buildArgs != null && !buildArgs.isEmpty()) { for (String buildArg : buildArgs) { if(buildArg.startsWith("\\Q") || - buildArg.startsWith("--H:ConfigurationFileDirectories")) { + buildArg.startsWith("-H:ConfigurationFileDirectories")) { cliArgs.add(buildArg); continue; } @@ -252,7 +252,7 @@ protected List getBuildArgs() throws MojoExecutionException { int i=0; while(i < args.length) { String a =args[i]; - if (a.startsWith(""+System.getProperty("user.home").charAt(0))) { + if (a.charAt(0) == System.getProperty("user.home").charAt(0)) { StringBuilder path = new StringBuilder(a); i++; while( i< args.length && args[i].toLowerCase().charAt(0) <= 'z' && 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 00c593bc6..8bd27d470 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 @@ -49,12 +49,15 @@ import org.eclipse.jetty.server.handler.ResourceHandler import spock.lang.Specification import spock.lang.TempDir +import java.nio.file.FileVisitResult import java.nio.file.Files import java.nio.file.Path +import java.nio.file.SimpleFileVisitor import java.nio.file.StandardCopyOption +import java.nio.file.attribute.BasicFileAttributes abstract class AbstractGraalVMMavenFunctionalTest extends Specification { - @TempDir + Path testDirectory Path testOrigin; @@ -71,6 +74,13 @@ abstract class AbstractGraalVMMavenFunctionalTest extends Specification { boolean IS_MAC = System.getProperty("os.name", "unknown").contains("Mac"); def setup() { + var home_dir = Path.of(System.getProperty("user.home")) + testDirectory = home_dir.resolve("tests") + + if (Files.notExists(testDirectory)) { + Files.createDirectory(testDirectory) + } + executor = new IsolatedMavenExecutor( new File(System.getProperty("java.executable")), testDirectory.resolve("m2-home").toFile(), @@ -79,6 +89,21 @@ abstract class AbstractGraalVMMavenFunctionalTest extends Specification { } def cleanup() { + + //cleanup test directory and all it's sub directories + Files.walkFileTree(testDirectory, new SimpleFileVisitor() { + @Override + FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + Files.delete(file); + return FileVisitResult.CONTINUE; + } + @Override + FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + Files.delete(dir); + return FileVisitResult.CONTINUE; + } + }); + if (server != null) { server.stop() server.destroy() @@ -158,7 +183,7 @@ abstract class AbstractGraalVMMavenFunctionalTest extends Specification { 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 + "maven.repo.local": testDirectory.resolve("local repo").toFile().absolutePath ] resultingSystemProperties.putAll(systemProperties) From 5a865160f4c9c3c904e4fa0fcdfcbc01b64666f9 Mon Sep 17 00:00:00 2001 From: lahoucine el addali Date: Tue, 6 Aug 2024 14:48:15 +0100 Subject: [PATCH 19/36] split build arguments correcltly --- .../maven/AbstractNativeImageMojo.java | 22 ++----------------- .../AbstractGraalVMMavenFunctionalTest.groovy | 6 ++--- 2 files changed, 4 insertions(+), 24 deletions(-) diff --git a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java index c05e2f37e..339ae4a3a 100644 --- a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java +++ b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java @@ -243,29 +243,11 @@ protected List getBuildArgs() throws MojoExecutionException { if (buildArgs != null && !buildArgs.isEmpty()) { for (String buildArg : buildArgs) { - if(buildArg.startsWith("\\Q") || - buildArg.startsWith("-H:ConfigurationFileDirectories")) { + if(buildArg.startsWith("\\Q") || buildArg.startsWith("-H")) { cliArgs.add(buildArg); continue; } - String[] args = buildArg.split("\\s+"); - int i=0; - while(i < args.length) { - String a =args[i]; - if (a.charAt(0) == System.getProperty("user.home").charAt(0)) { - StringBuilder path = new StringBuilder(a); - i++; - while( i< args.length && args[i].toLowerCase().charAt(0) <= 'z' && - args[i].toLowerCase().charAt(0) >= 'a') { - path.append(" ").append(args[i]); - i++; - } - cliArgs.add(path.toString()); - } else { - cliArgs.add(a); - i++; - } - } + cliArgs.addAll(Arrays.asList(buildArg.split("\\s+", 2))); } } 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 8bd27d470..eea14f561 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 @@ -74,8 +74,8 @@ abstract class AbstractGraalVMMavenFunctionalTest extends Specification { boolean IS_MAC = System.getProperty("os.name", "unknown").contains("Mac"); def setup() { - var home_dir = Path.of(System.getProperty("user.home")) - testDirectory = home_dir.resolve("tests") + Path HomeDir = Path.of(System.getProperty("user.home")) + testDirectory = HomeDir.resolve("tests") if (Files.notExists(testDirectory)) { Files.createDirectory(testDirectory) @@ -89,8 +89,6 @@ abstract class AbstractGraalVMMavenFunctionalTest extends Specification { } def cleanup() { - - //cleanup test directory and all it's sub directories Files.walkFileTree(testDirectory, new SimpleFileVisitor() { @Override FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { From 7bb291c1835864bd4e859e02467c278c09c92053 Mon Sep 17 00:00:00 2001 From: Vojin Jovanovic Date: Mon, 12 Aug 2024 22:09:24 +0200 Subject: [PATCH 20/36] Adjust native-build tools to reachability-metadata.json --- ...aApplicationWithAgentFunctionalTest.groovy | 38 +++++++++---------- .../internal/DefaultGraalVmExtension.java | 3 +- .../tasks/actions/MergeAgentFilesAction.java | 6 ++- .../buildtools/maven/MetadataCopyMojo.java | 8 ++-- 4 files changed, 29 insertions(+), 26 deletions(-) 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 15e976132..7135db226 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 @@ -46,6 +46,10 @@ import spock.lang.Unroll class JavaApplicationWithAgentFunctionalTest extends AbstractFunctionalTest { + def metadataExistsAt(String path) { + file("${path}/reachability-metadata.json").exists() + } + @Unroll("agent is not passed and the application fails with JUnit Platform #junitVersion") def "agent is not passed"() { given: @@ -94,18 +98,13 @@ class JavaApplicationWithAgentFunctionalTest extends AbstractFunctionalTest { """.trim() and: - ['jni', 'proxy', 'reflect', 'resource', 'serialization'].each { name -> - assert file("build/native/agent-output/test/${name}-config.json").exists() - } + assert metadataExistsAt("build/native/agent-output/test") when: run 'metadataCopy' then: - ['jni', 'proxy', 'reflect', 'resource', 'serialization'].each { name -> - assert file("build/native/metadataCopyTest/${name}-config.json").exists() - } - + assert metadataExistsAt("build/native/metadataCopyTest") where: junitVersion = System.getProperty('versions.junit') @@ -125,7 +124,7 @@ class JavaApplicationWithAgentFunctionalTest extends AbstractFunctionalTest { } and: - assert file("build/native/agent-output/test/reflect-config.json").text.contains("\"condition\"") + assert file("build/native/agent-output/test/reachability-metadata.json").text.contains("\"condition\"") where: junitVersion = System.getProperty('versions.junit') @@ -148,22 +147,21 @@ class JavaApplicationWithAgentFunctionalTest extends AbstractFunctionalTest { } and: - ['jni', 'proxy', 'reflect', 'resource', 'serialization'].each { name -> - assert file("build/native/agent-output/run/${name}-config.json").exists() - } + assert metadataExistsAt("build/native/agent-output/run") when: - run'metadataCopy', '--task', 'run', '--dir', metadata_dir + run 'metadataCopy', '--task', 'run', '--dir', metadata_dir then: - ['jni', 'proxy', 'reflect', 'resource', 'serialization'].each { name -> - assert file("${metadata_dir}/${name}-config.json").exists() - } + assert metadataExistsAt(metadata_dir) and: - var reflect_config = file("${metadata_dir}/reflect-config.json") - var reflect_config_contents = reflect_config.text - assert reflect_config_contents.contains("DummyClass") && reflect_config_contents.contains("org.graalvm.demo.Message") + var reachabilityMetadata = file("${metadata_dir}/reachability-metadata.json") + var reachabilityMetadataContents = reachabilityMetadata.text + println reachabilityMetadataContents + assert reachabilityMetadataContents.contains("DummyClass"), reachabilityMetadataContents + assert reachabilityMetadataContents.contains("org.graalvm.demo.Message"), reachabilityMetadataContents + when: run 'nativeRun' @@ -190,9 +188,7 @@ class JavaApplicationWithAgentFunctionalTest extends AbstractFunctionalTest { } and: - ['jni', 'proxy', 'reflect', 'resource', 'serialization'].each { name -> - assert file("build/native/agent-output/run/${name}-config.json").exists() - } + assert metadataExistsAt("build/native/agent-output/run") when: run'run', '-Pagent', '--configuration-cache', '--rerun-tasks' 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 1d4235f6c..82c1cebf3 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 @@ -79,7 +79,8 @@ public DefaultGraalVmExtension(NamedDomainObjectContainer na agentOpts.getEnabled().convention(false); agentOpts.getModes().getConditional().getParallel().convention(true); agentOpts.getMetadataCopy().getMergeWithExisting().convention(false); - agentOpts.getFilterableEntries().convention(Arrays.asList("org.gradle.", "org.junit.")); + // TODO: replace with agent access filter + // 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/tasks/actions/MergeAgentFilesAction.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/tasks/actions/MergeAgentFilesAction.java index 013479ce4..8e0e5ed99 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 @@ -58,6 +58,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Set; import java.util.function.Supplier; import static org.graalvm.buildtools.gradle.internal.NativeImageExecutableLocator.findNativeImageExecutable; @@ -94,8 +95,11 @@ public MergeAgentFilesAction(Provider isMergingEnabled, this.noLauncherProperty = objectFactory.property(JavaLauncher.class); } + private static final Set metadataFiles = Set.of("reflect-config.json", "jni-config.json", "proxy-config.json", "resource-config.json", "reachability-metadata.json"); + private static boolean isConfigDir(String dir) { - return Arrays.stream(new File(dir).listFiles()).anyMatch(file -> file.getName().equals("reflect-config.json")); + return Arrays.stream(new File(dir).listFiles()) + .anyMatch(file -> metadataFiles.contains(file.getName())); } @Override diff --git a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/MetadataCopyMojo.java b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/MetadataCopyMojo.java index 267a40498..67b7b5494 100644 --- a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/MetadataCopyMojo.java +++ b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/MetadataCopyMojo.java @@ -66,7 +66,8 @@ public class MetadataCopyMojo extends AbstractMergeAgentFilesMojo { private static final String DEFAULT_OUTPUT_DIRECTORY = "/META-INF/native-image"; - private static final List FILES_REQUIRED_FOR_MERGE = Arrays.asList("reflect-config.json", "jni-config.json", "proxy-config.json", "resource-config.json"); + private static final List FILES_REQUIRED_FOR_MERGE_LEGACY = Arrays.asList("reflect-config.json", "jni-config.json", "proxy-config.json", "resource-config.json"); + private static final List FILES_REQUIRED_FOR_MERGE = Arrays.asList("reachability-metadata.json"); @Parameter(alias = "agent") private AgentConfiguration agentConfiguration; @@ -136,7 +137,7 @@ private void executeCopy(String buildDirectory, String destinationDir) throws Mo throw new MojoExecutionException("There are missing files for merge in output directory. If you want to merge agent files with " + "existing files in output directory, please make sure that output directory contains all of the following files: " + - "reflect-config.json, jni-config.json, proxy-config.json, resource-config.json. Currently the output directory is " + + "reflect-config.json, jni-config.json, proxy-config.json, resource-config.json, reachability-metadata.json. Currently the output directory is " + "missing: " + missingFiles); } @@ -209,7 +210,8 @@ private boolean dirContainsFilesForMerge(String dir) { } List dirContent = Arrays.stream(content).map(File::getName).collect(Collectors.toList()); - return getListDiff(FILES_REQUIRED_FOR_MERGE, dirContent).isEmpty(); + return getListDiff(FILES_REQUIRED_FOR_MERGE, dirContent).isEmpty() || + getListDiff(FILES_REQUIRED_FOR_MERGE_LEGACY, dirContent).isEmpty(); } private List getListDiff(List list1, List list2) { From e5d055aa4cc160828552b47718ff36d82bdc066c Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Tue, 13 Aug 2024 16:55:53 +0200 Subject: [PATCH 21/36] Perform differnet checks in tests based on jdk version --- ...aApplicationWithAgentFunctionalTest.groovy | 46 +++++++++++++++---- .../internal/DefaultGraalVmExtension.java | 1 - .../gradle/fixtures/GraalVMSupport.groovy | 20 ++++++++ 3 files changed, 58 insertions(+), 9 deletions(-) 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 7135db226..3f39e6852 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,12 +42,33 @@ package org.graalvm.buildtools.gradle import org.graalvm.buildtools.gradle.fixtures.AbstractFunctionalTest +import org.graalvm.buildtools.gradle.fixtures.GraalVMSupport +import org.graalvm.buildtools.utils.NativeImageUtils import spock.lang.Unroll class JavaApplicationWithAgentFunctionalTest extends AbstractFunctionalTest { + def getCurrentJDKVersion() { + return NativeImageUtils.getMajorJDKVersion(GraalVMSupport.getGraalVMHomeVersionString()) + } + + def metadataInSingleConfigFile() { + return getCurrentJDKVersion() >= 23 + } + def metadataExistsAt(String path) { - file("${path}/reachability-metadata.json").exists() + if (metadataInSingleConfigFile()) { + return file("${path}/reachability-metadata.json").exists() + } + + boolean allFilesExist = true + ['jni', 'proxy', 'reflect', 'resource', 'serialization'].each { name -> + if (!file("${path}/${name}-config.json").exists()) { + allFilesExist = false + } + } + + return allFilesExist } @Unroll("agent is not passed and the application fails with JUnit Platform #junitVersion") @@ -124,7 +145,11 @@ class JavaApplicationWithAgentFunctionalTest extends AbstractFunctionalTest { } and: - assert file("build/native/agent-output/test/reachability-metadata.json").text.contains("\"condition\"") + if (metadataInSingleConfigFile()) { + assert file("build/native/agent-output/test/reachability-metadata.json").text.contains("\"condition\"") + } else { + assert file("build/native/agent-output/test/reflect-config.json").text.contains("\"condition\"") + } where: junitVersion = System.getProperty('versions.junit') @@ -156,12 +181,17 @@ class JavaApplicationWithAgentFunctionalTest extends AbstractFunctionalTest { assert metadataExistsAt(metadata_dir) and: - var reachabilityMetadata = file("${metadata_dir}/reachability-metadata.json") - var reachabilityMetadataContents = reachabilityMetadata.text - println reachabilityMetadataContents - assert reachabilityMetadataContents.contains("DummyClass"), reachabilityMetadataContents - assert reachabilityMetadataContents.contains("org.graalvm.demo.Message"), reachabilityMetadataContents - + if (metadataInSingleConfigFile()) { + var reachabilityMetadata = file("${metadata_dir}/reachability-metadata.json") + var reachabilityMetadataContents = reachabilityMetadata.text + println reachabilityMetadataContents + assert reachabilityMetadataContents.contains("DummyClass"), reachabilityMetadataContents + assert reachabilityMetadataContents.contains("org.graalvm.demo.Message"), reachabilityMetadataContents + } else { + var reflect_config = file("${metadata_dir}/reflect-config.json") + var reflect_config_contents = reflect_config.text + assert reflect_config_contents.contains("DummyClass") && reflect_config_contents.contains("org.graalvm.demo.Message") + } when: run 'nativeRun' 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 82c1cebf3..c5c04a37d 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 @@ -55,7 +55,6 @@ import org.gradle.jvm.toolchain.JavaToolchainService; import javax.inject.Inject; -import java.util.Arrays; public abstract class DefaultGraalVmExtension implements GraalVMExtension { private final transient NamedDomainObjectContainer nativeImages; diff --git a/native-gradle-plugin/src/testFixtures/groovy/org/graalvm/buildtools/gradle/fixtures/GraalVMSupport.groovy b/native-gradle-plugin/src/testFixtures/groovy/org/graalvm/buildtools/gradle/fixtures/GraalVMSupport.groovy index 9c357ebd6..d67708a05 100644 --- a/native-gradle-plugin/src/testFixtures/groovy/org/graalvm/buildtools/gradle/fixtures/GraalVMSupport.groovy +++ b/native-gradle-plugin/src/testFixtures/groovy/org/graalvm/buildtools/gradle/fixtures/GraalVMSupport.groovy @@ -53,6 +53,26 @@ class GraalVMSupport { (System.getProperty("java.vendor.version", "") - 'GraalVM' - 'CE' - 'EE').trim() } + static String getJavaHomeVersionString() { + String javaHomeLocation = System.getenv("JAVA_HOME") + return extractVersionString(javaHomeLocation) + } + + static String getGraalVMHomeVersionString() { + String graalvmHomeLocation = System.getenv("GRAALVM_HOME") + return extractVersionString(graalvmHomeLocation) + } + + private static String extractVersionString(String location) { + def sout = new StringBuilder(), serr = new StringBuilder() + def proc = (location + '/bin/native-image --version').execute() + proc.consumeProcessOutput(sout, serr) + proc.waitForOrKill(1000) + assert serr.toString().isEmpty() + + return sout.toString() + } + static int getMajorVersion() { String v = version v.substring(0, v.indexOf('.')).toInteger() From 04e873544054cf812be9c1f4e3ec5558db52ae20 Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Tue, 13 Aug 2024 17:53:54 +0200 Subject: [PATCH 22/36] Execute different version commands based on the system --- .../buildtools/gradle/fixtures/GraalVMSupport.groovy | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/native-gradle-plugin/src/testFixtures/groovy/org/graalvm/buildtools/gradle/fixtures/GraalVMSupport.groovy b/native-gradle-plugin/src/testFixtures/groovy/org/graalvm/buildtools/gradle/fixtures/GraalVMSupport.groovy index d67708a05..08b034fb8 100644 --- a/native-gradle-plugin/src/testFixtures/groovy/org/graalvm/buildtools/gradle/fixtures/GraalVMSupport.groovy +++ b/native-gradle-plugin/src/testFixtures/groovy/org/graalvm/buildtools/gradle/fixtures/GraalVMSupport.groovy @@ -65,7 +65,8 @@ class GraalVMSupport { private static String extractVersionString(String location) { def sout = new StringBuilder(), serr = new StringBuilder() - def proc = (location + '/bin/native-image --version').execute() + String command = getSystemBasedCommand(location); + def proc = command.execute() proc.consumeProcessOutput(sout, serr) proc.waitForOrKill(1000) assert serr.toString().isEmpty() @@ -82,4 +83,12 @@ class GraalVMSupport { String v = version - "${majorVersion}." v.substring(0, v.indexOf('.')).toInteger() } + + private static boolean getSystemBasedCommand(String location) { + if (System.getProperty("os.name", "unknown").contains("Windows")) { + return location + '\\bin\\native-image.cmd --version' + } else { + return location + '/bin/native-image --version' + } + } } From 07737516eb701b5f4bbc273ff1ff28ea70a853c7 Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Wed, 14 Aug 2024 14:28:09 +0200 Subject: [PATCH 23/36] Fix return type of command generating function --- .../graalvm/buildtools/gradle/fixtures/GraalVMSupport.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/native-gradle-plugin/src/testFixtures/groovy/org/graalvm/buildtools/gradle/fixtures/GraalVMSupport.groovy b/native-gradle-plugin/src/testFixtures/groovy/org/graalvm/buildtools/gradle/fixtures/GraalVMSupport.groovy index 08b034fb8..344bccee4 100644 --- a/native-gradle-plugin/src/testFixtures/groovy/org/graalvm/buildtools/gradle/fixtures/GraalVMSupport.groovy +++ b/native-gradle-plugin/src/testFixtures/groovy/org/graalvm/buildtools/gradle/fixtures/GraalVMSupport.groovy @@ -84,7 +84,7 @@ class GraalVMSupport { v.substring(0, v.indexOf('.')).toInteger() } - private static boolean getSystemBasedCommand(String location) { + private static String getSystemBasedCommand(String location) { if (System.getProperty("os.name", "unknown").contains("Windows")) { return location + '\\bin\\native-image.cmd --version' } else { From 1411a607907df518fb6a63d31e4fa406d03759db Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Wed, 21 Aug 2024 18:15:23 +0200 Subject: [PATCH 24/36] Simplify file existence check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cédric Champeau --- .../gradle/JavaApplicationWithAgentFunctionalTest.groovy | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) 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 3f39e6852..7d8566b6a 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 @@ -61,11 +61,8 @@ class JavaApplicationWithAgentFunctionalTest extends AbstractFunctionalTest { return file("${path}/reachability-metadata.json").exists() } - boolean allFilesExist = true - ['jni', 'proxy', 'reflect', 'resource', 'serialization'].each { name -> - if (!file("${path}/${name}-config.json").exists()) { - allFilesExist = false - } + boolean allFilesExist = ['jni', 'proxy', 'reflect', 'resource', 'serialization'].every { name -> + file("${path}/${name}-config.json").exists() } return allFilesExist From 1a8fddd1bf582b37e3737caa8a854597f5f1458d Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Wed, 21 Aug 2024 18:16:50 +0200 Subject: [PATCH 25/36] Use capital case for static variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cédric Champeau --- .../buildtools/gradle/tasks/actions/MergeAgentFilesAction.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 8e0e5ed99..0408c740f 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 @@ -95,7 +95,7 @@ public MergeAgentFilesAction(Provider isMergingEnabled, this.noLauncherProperty = objectFactory.property(JavaLauncher.class); } - private static final Set metadataFiles = Set.of("reflect-config.json", "jni-config.json", "proxy-config.json", "resource-config.json", "reachability-metadata.json"); + private static final Set METADATA_FILES = Set.of("reflect-config.json", "jni-config.json", "proxy-config.json", "resource-config.json", "reachability-metadata.json"); private static boolean isConfigDir(String dir) { return Arrays.stream(new File(dir).listFiles()) From a02c0421936d644c6418f18d4619190905dbff94 Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Wed, 21 Aug 2024 18:17:19 +0200 Subject: [PATCH 26/36] Refactor code after variable renaming MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cédric Champeau --- .../buildtools/gradle/tasks/actions/MergeAgentFilesAction.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 0408c740f..e2040b9b2 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 @@ -99,7 +99,7 @@ public MergeAgentFilesAction(Provider isMergingEnabled, private static boolean isConfigDir(String dir) { return Arrays.stream(new File(dir).listFiles()) - .anyMatch(file -> metadataFiles.contains(file.getName())); + .anyMatch(file -> METADATA_FILES.contains(file.getName())); } @Override From 9e9703ce6be9cd57a57c691da9b4d1d776211a94 Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Thu, 29 Aug 2024 16:03:42 +0200 Subject: [PATCH 27/36] Use access-filter for filtering gradle and junit metadata --- .../buildtools/agent/AgentConfiguration.java | 23 +++ .../src/main/resources/access-filter.json | 13 ++ .../buildtools/gradle/NativeImagePlugin.java | 6 - .../internal/DefaultGraalVmExtension.java | 2 - ...cessGeneratedGraalResourceFilesAction.java | 166 ------------------ 5 files changed, 36 insertions(+), 174 deletions(-) create mode 100644 common/utils/src/main/resources/access-filter.json delete mode 100644 native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/tasks/actions/ProcessGeneratedGraalResourceFilesAction.java diff --git a/common/utils/src/main/java/org/graalvm/buildtools/agent/AgentConfiguration.java b/common/utils/src/main/java/org/graalvm/buildtools/agent/AgentConfiguration.java index 105311a43..63bb59dbf 100644 --- a/common/utils/src/main/java/org/graalvm/buildtools/agent/AgentConfiguration.java +++ b/common/utils/src/main/java/org/graalvm/buildtools/agent/AgentConfiguration.java @@ -40,13 +40,21 @@ */ package org.graalvm.buildtools.agent; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; import java.io.Serializable; +import java.nio.file.CopyOption; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; import java.util.ArrayList; import java.util.Collection; import java.util.List; public class AgentConfiguration implements Serializable { + private static final String DEFAULT_ACCESS_FILTER_FILE = "/access-filter.json"; private final Collection callerFilterFiles; private final Collection accessFilterFiles; private final Boolean builtinCallerFilter; @@ -79,6 +87,7 @@ public AgentConfiguration(Collection callerFilterFiles, AgentMode agentMode) { this.callerFilterFiles = callerFilterFiles; this.accessFilterFiles = accessFilterFiles; + addDefaultAccessFilter(); this.builtinCallerFilter = builtinCallerFilter; this.builtinHeuristicFilter = builtinHeuristicFilter; this.experimentalPredefinedClasses = experimentalPredefinedClasses; @@ -127,4 +136,18 @@ private void addToCmd(String option, Boolean value, List cmdLine) { } } + private void addDefaultAccessFilter() { + try(InputStream accessFilter = AgentConfiguration.class.getResourceAsStream(DEFAULT_ACCESS_FILTER_FILE)) { + if (accessFilter != null) { + Path accessFilterPath = Files.createTempFile("access-filter", ".json"); + Files.copy(accessFilter, accessFilterPath, StandardCopyOption.REPLACE_EXISTING); + accessFilterFiles.add(accessFilterPath.toString()); + } else { + throw new IOException("Cannot find access-filter.json on default location: " + DEFAULT_ACCESS_FILTER_FILE); + } + } catch (IOException e) { + throw new RuntimeException("Cannot add default access-filter.json" ,e); + } + } + } diff --git a/common/utils/src/main/resources/access-filter.json b/common/utils/src/main/resources/access-filter.json new file mode 100644 index 000000000..4781418b7 --- /dev/null +++ b/common/utils/src/main/resources/access-filter.json @@ -0,0 +1,13 @@ +{ + "rules": [ + { + "includeClasses": "**" + }, + { + "excludeClasses": "org.gradle.**" + }, + { + "excludeClasses": "org.junit.**" + } + ] +} \ No newline at end of file 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 89685b41d..dfa3b521a 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 @@ -64,7 +64,6 @@ import org.graalvm.buildtools.gradle.tasks.NativeRunTask; import org.graalvm.buildtools.gradle.tasks.actions.CleanupAgentFilesAction; 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; @@ -871,11 +870,6 @@ public void execute(@Nonnull Task task) { execOperations)); taskToInstrument.doLast(new CleanupAgentFilesAction(mergeInputDirs, fileOperations)); - - taskToInstrument.doLast(new ProcessGeneratedGraalResourceFilesAction( - outputDir, - graalExtension.getAgent().getFilterableEntries() - )); } private static void injectTestPluginDependencies(Project project, Property testSupportEnabled) { 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 c5c04a37d..9bc4d1662 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 @@ -78,8 +78,6 @@ public DefaultGraalVmExtension(NamedDomainObjectContainer na agentOpts.getEnabled().convention(false); agentOpts.getModes().getConditional().getParallel().convention(true); agentOpts.getMetadataCopy().getMergeWithExisting().convention(false); - // TODO: replace with agent access filter - // 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/tasks/actions/ProcessGeneratedGraalResourceFilesAction.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/tasks/actions/ProcessGeneratedGraalResourceFilesAction.java deleted file mode 100644 index aaefbd3a0..000000000 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/tasks/actions/ProcessGeneratedGraalResourceFilesAction.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * 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.tasks.actions; - -import groovy.json.JsonGenerator; -import groovy.json.JsonOutput; -import groovy.json.JsonSlurper; -import org.gradle.api.Action; -import org.gradle.api.GradleException; -import org.gradle.api.Task; -import org.gradle.api.file.Directory; -import org.gradle.api.provider.ListProperty; -import org.gradle.api.provider.Provider; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * This task is responsible for processing the JSON files generated by - * the GraalVM agent, in particular to filter out entries which are - * inherited from the Gradle environment itself. - */ -public class ProcessGeneratedGraalResourceFilesAction implements Action { - private final Provider inputDirectory; - private final ListProperty filterableEntries; - - public ProcessGeneratedGraalResourceFilesAction(Provider inputDirectory, ListProperty filterableEntries) { - this.inputDirectory = inputDirectory; - this.filterableEntries = filterableEntries; - } - - @Override - public void execute(Task task) { - try { - for (File resourceFile : inputDirectory.get().getAsFileTree()) { - processFile(resourceFile); - } - } catch (IOException e) { - throw new GradleException("An IO error occured when processing the agent generated files", e); - } - } - - protected void processFile(File file) throws IOException { - if (file.getName().endsWith(".json")) { - processJsonFile(file); - } - } - - protected void processJsonFile(File jsonFile) throws IOException { - JsonSlurper json = new JsonSlurper(); - Object result = json.parse(jsonFile); - Object filtered = filter(result); - JsonGenerator generator = new JsonGenerator.Options() - .build(); - String processed = JsonOutput.prettyPrint(generator.toJson(filtered)); - try (Writer writer = new OutputStreamWriter(new FileOutputStream(jsonFile), StandardCharsets.UTF_8)) { - writer.write(processed); - } - } - - /** - * Filters the parsed JSON file to remove entries which are configured - * by the filterable entries parameter. This is a very rough algorithm - * which would deserve specific implementation for each JSON format. - * Instead it takes a "brute force" approach which may result in some - * weird errors. - */ - @SuppressWarnings("unchecked") - private Object filter(Object in) { - Class clazz = in.getClass(); - if (shouldFilterString(in)) { - return null; - } - if (List.class.isAssignableFrom(clazz)) { - return filterList((List) in); - } - if (Map.class.isAssignableFrom(clazz)) { - return filterMap((Map) in); - } - return in; - } - - private Map filterMap(Map map) { - if (shouldFilterString(map.get("name"))) { - return null; - } - Map out = new HashMap<>(map.size()); - for (Map.Entry entry : map.entrySet()) { - Object key = entry.getKey(); - Object value = entry.getValue(); - if (shouldFilterString(value)) { - continue; - } - out.put(key, filter(value)); - } - return out; - } - - private boolean shouldFilterString(Object value) { - if (value instanceof CharSequence) { - String string = value.toString(); - return filterableEntries.get().stream().anyMatch(string::startsWith); - } - return false; - } - - private List filterList(List in) { - List out = new ArrayList<>(in.size()); - for (Object element : in) { - Object filtered = filter(element); - if (filtered == null || (filtered instanceof Collection && ((Collection) filtered).isEmpty())) { - continue; - } - out.add(filtered); - } - return out; - } -} From ef4b53629872a5e246377a083ea2cd9cc4d0cc43 Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Tue, 3 Sep 2024 14:02:09 +0200 Subject: [PATCH 28/36] Add access-filter file with fixed path --- .../buildtools/agent/AgentConfiguration.java | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/common/utils/src/main/java/org/graalvm/buildtools/agent/AgentConfiguration.java b/common/utils/src/main/java/org/graalvm/buildtools/agent/AgentConfiguration.java index 63bb59dbf..2072b4cdb 100644 --- a/common/utils/src/main/java/org/graalvm/buildtools/agent/AgentConfiguration.java +++ b/common/utils/src/main/java/org/graalvm/buildtools/agent/AgentConfiguration.java @@ -87,7 +87,6 @@ public AgentConfiguration(Collection callerFilterFiles, AgentMode agentMode) { this.callerFilterFiles = callerFilterFiles; this.accessFilterFiles = accessFilterFiles; - addDefaultAccessFilter(); this.builtinCallerFilter = builtinCallerFilter; this.builtinHeuristicFilter = builtinHeuristicFilter; this.experimentalPredefinedClasses = experimentalPredefinedClasses; @@ -97,6 +96,7 @@ public AgentConfiguration(Collection callerFilterFiles, } public List getAgentCommandLine() { + addDefaultAccessFilter(); List cmdLine = new ArrayList<>(agentMode.getAgentCommandLine()); appendOptionToValues("caller-filter-file=", callerFilterFiles, cmdLine); appendOptionToValues("access-filter-file=", accessFilterFiles, cmdLine); @@ -137,11 +137,27 @@ private void addToCmd(String option, Boolean value, List cmdLine) { } private void addDefaultAccessFilter() { + if (accessFilterFiles == null) { + // this could only happen if we instantiated disabled agent configuration + return; + } + + String tempDir = System.getProperty("java.io.tmpdir"); + Path agentDir = Path.of(tempDir).resolve("agent-config"); + Path accessFilterFile = agentDir.resolve("access-filter.json"); + if (Files.exists(accessFilterFile)) { + accessFilterFiles.add(accessFilterFile.toString()); + return; + } + try(InputStream accessFilter = AgentConfiguration.class.getResourceAsStream(DEFAULT_ACCESS_FILTER_FILE)) { if (accessFilter != null) { - Path accessFilterPath = Files.createTempFile("access-filter", ".json"); - Files.copy(accessFilter, accessFilterPath, StandardCopyOption.REPLACE_EXISTING); - accessFilterFiles.add(accessFilterPath.toString()); + if (!Files.exists(agentDir)) { + Files.createDirectory(agentDir); + } + + Files.copy(accessFilter, accessFilterFile, StandardCopyOption.REPLACE_EXISTING); + accessFilterFiles.add(accessFilterFile.toString()); } else { throw new IOException("Cannot find access-filter.json on default location: " + DEFAULT_ACCESS_FILTER_FILE); } From a221227c23c35c84d0fb06a5db0eaaac7507b51e Mon Sep 17 00:00:00 2001 From: linghengqian Date: Thu, 13 Jun 2024 23:14:58 +0800 Subject: [PATCH 29/36] Fixes the issue that nativeTest cannot be executed using Junit 5.11.0-M2 --- .../platform/config/platform/PlatformConfigProvider.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 d9c03eb16..4b94023b1 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 @@ -60,7 +60,9 @@ public void onLoad(NativeImageConfiguration config) { "org.junit.platform.engine.UniqueIdFormat", "org.junit.platform.commons.util.ReflectionUtils", // https://github.com/graalvm/native-build-tools/issues/300 - "org.junit.platform.reporting.open.xml.OpenTestReportGeneratingListener" + "org.junit.platform.reporting.open.xml.OpenTestReportGeneratingListener", + // https://github.com/graalvm/native-build-tools/issues/602 + "org.junit.platform.commons.util.LruCache" ); if (getMajorJDKVersion() >= 21) { From 357b7475c4cbffd1e6ffa081f26bcbf1f8a50b14 Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Tue, 3 Sep 2024 14:42:39 +0200 Subject: [PATCH 30/36] Bump metadata repository version to 0.3.9 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 90e2120df..a6f9882a1 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,7 +1,7 @@ [versions] # Project versions nativeBuildTools = "0.10.3-SNAPSHOT" -metadataRepository = "0.3.8" +metadataRepository = "0.3.9" # External dependencies spock = "2.1-groovy-3.0" From 0a05df5ed491c118820881f5011abb24a6983928 Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Tue, 3 Sep 2024 15:13:03 +0200 Subject: [PATCH 31/36] Fix broken link for quick build mode --- docs/src/docs/asciidoc/maven-plugin.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/docs/asciidoc/maven-plugin.adoc b/docs/src/docs/asciidoc/maven-plugin.adoc index 67d6eaf89..46edea173 100644 --- a/docs/src/docs/asciidoc/maven-plugin.adoc +++ b/docs/src/docs/asciidoc/maven-plugin.adoc @@ -173,7 +173,7 @@ Build Configuration]. It is also possible to customize the plugin within a true ---- ``:: - If you want to build the image using https://blogs.oracle.com/java/post/graalvm-enterprise-221--faster-smarter-leaner[quick build mode], supply the following in the configuration of the plugin (alternatively set the `GRAALVM_QUICK_BUILD` environment variable to `true`): + If you want to build the image using https://www.graalvm.org/latest/reference-manual/native-image/overview/BuildOutput/#qbm-use-quick-build-mode-for-faster-builds[quick build mode], supply the following in the configuration of the plugin (alternatively set the `GRAALVM_QUICK_BUILD` environment variable to `true`): [source,xml] ---- true From 3fdca05ddc27e814fe291879e08f9ac9036f2a79 Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Tue, 3 Sep 2024 14:48:59 +0200 Subject: [PATCH 32/36] Add missing changelog entries --- docs/src/docs/asciidoc/index.adoc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index d14e45e0b..703456ede 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -22,6 +22,8 @@ If you are using alternative build systems, see < Date: Fri, 30 Aug 2024 16:36:44 +0200 Subject: [PATCH 33/36] Fix error message when the JDK is not a GraalVM --- .../NativeImageExecutableLocator.java | 42 +++++++++---------- .../utils/NativeImageConfigurationUtils.java | 31 +++++++------- 2 files changed, 35 insertions(+), 38 deletions(-) diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/NativeImageExecutableLocator.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/NativeImageExecutableLocator.java index ae05fcb61..0a77f440d 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/NativeImageExecutableLocator.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/NativeImageExecutableLocator.java @@ -91,29 +91,29 @@ public static File findNativeImageExecutable(Property javaLauncher executablePath = metadata.getInstallationPath().file("bin/" + NATIVE_IMAGE_EXE).getAsFile(); } - try { - if (!executablePath.exists()) { - logger.log("Native Image executable wasn't found. We will now try to download it. "); - File graalVmHomeGuess = executablePath.getParentFile(); - - File guPath = graalVmHomeGuess.toPath().resolve(GU_EXE).toFile(); - if (!guPath.exists()) { - throw new GradleException("'" + GU_EXE + "' at '" + guPath + "' tool wasn't found. This probably means that JDK at isn't a GraalVM distribution."); - } - ExecResult res = execOperations.exec(spec -> { - spec.args("install", "native-image"); - spec.setExecutable(Paths.get(graalVmHomeGuess.getAbsolutePath(), GU_EXE)); - }); - if (res.getExitValue() != 0) { - throw new GradleException("Native Image executable wasn't found, and '" + GU_EXE + "' tool failed to install it."); - } - diagnostics.withGuInstall(); + File graalVmHomeGuess = executablePath.getParentFile(); + File guPath = graalVmHomeGuess.toPath().resolve(GU_EXE).toFile(); + if (guPath.exists() && !executablePath.exists()) { + logger.log("Native Image executable wasn't found. We will now try to download it. "); + + ExecResult res = execOperations.exec(spec -> { + spec.args("install", "native-image"); + spec.setExecutable(Paths.get(graalVmHomeGuess.getAbsolutePath(), GU_EXE)); + }); + if (res.getExitValue() != 0) { + throw new GradleException("Native Image executable wasn't found, and '" + GU_EXE + "' tool failed to install it.\n" + + "Make sure to declare the GRAALVM_HOME or JAVA_HOME environment variable or install GraalVM with " + + "native-image in a standard location recognized by Gradle Java toolchain support"); } - } catch (GradleException e) { - throw new GradleException("Determining GraalVM installation failed with message: " + e.getMessage() + "\n\n" - + "Make sure to declare the GRAALVM_HOME environment variable or install GraalVM with " + - "native-image in a standard location recognized by Gradle Java toolchain support"); + diagnostics.withGuInstall(); } + + if (!executablePath.exists()) { + throw new GradleException(executablePath + " wasn't found. This probably means that JDK isn't a GraalVM distribution.\n" + + "Make sure to declare the GRAALVM_HOME or JAVA_HOME environment variable or install GraalVM with" + + "native-image in a standard location recognized by Gradle Java toolchain support"); + } + diagnostics.withExecutablePath(executablePath); return executablePath; } diff --git a/native-maven-plugin/src/main/java/org/graalvm/buildtools/utils/NativeImageConfigurationUtils.java b/native-maven-plugin/src/main/java/org/graalvm/buildtools/utils/NativeImageConfigurationUtils.java index e3401033b..364e051c6 100644 --- a/native-maven-plugin/src/main/java/org/graalvm/buildtools/utils/NativeImageConfigurationUtils.java +++ b/native-maven-plugin/src/main/java/org/graalvm/buildtools/utils/NativeImageConfigurationUtils.java @@ -69,34 +69,31 @@ public static Path getJavaHomeNativeImage(String javaHomeVariable, Boolean failF Path graalHomePath = Paths.get(graalHome); Path nativeImageExe = graalHomePath.resolve("bin").resolve(NATIVE_IMAGE_EXE); + Path guExe = graalHomePath.resolve("bin").resolve(GU_EXE); - if (!Files.exists(nativeImageExe)) { - Path guExe = graalHomePath.resolve("bin").resolve(GU_EXE); - if (Files.exists(guExe)) { - ProcessBuilder processBuilder = new ProcessBuilder(guExe.toString(), "install", "native-image"); - processBuilder.inheritIO(); - try { - Process nativeImageFetchingProcess = processBuilder.start(); - if (nativeImageFetchingProcess.waitFor() != 0) { - throw new MojoExecutionException("native-image was not found, and '" + GU_EXE + "' tool failed to install it."); - } - } catch (MojoExecutionException | IOException | InterruptedException e) { - throw new MojoExecutionException("Determining GraalVM installation failed with message: " + e.getMessage()); + if (Files.exists(guExe) && !Files.exists(nativeImageExe)) { + ProcessBuilder processBuilder = new ProcessBuilder(guExe.toString(), "install", "native-image"); + processBuilder.inheritIO(); + try { + Process nativeImageFetchingProcess = processBuilder.start(); + if (nativeImageFetchingProcess.waitFor() != 0) { + throw new MojoExecutionException("native-image was not found, and '" + GU_EXE + "' tool failed to install it."); } - } else if (failFast) { - throw new MojoExecutionException("'" + GU_EXE + "' tool was not found in your " + javaHomeVariable + "." + - "This probably means that the JDK at '" + graalHomePath + "' is not a GraalVM distribution."); + } catch (MojoExecutionException | IOException | InterruptedException e) { + throw new MojoExecutionException("Determining GraalVM installation failed with message: " + e.getMessage()); } } if (!Files.exists(nativeImageExe)) { if (failFast) { - throw new RuntimeException("native-image is not installed in your " + javaHomeVariable + "." + - "This probably means that the JDK at '" + graalHomePath + "' is not a GraalVM distribution."); + throw new MojoExecutionException("native-image is not installed in your " + javaHomeVariable + "." + + "This probably means that the JDK at '" + graalHomePath + "' is not a GraalVM distribution. " + + "The GraalVM Native Maven Plugin requires GRAALVM_HOME or JAVA_HOME to be a GraalVM distribution."); } else { return null; } } + logger.info("Found GraalVM installation from " + javaHomeVariable + " variable."); return nativeImageExe; } From 27986882a3e797b39ee5783a76706622791db347 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20S=C3=A1nchez-Mariscal?= Date: Wed, 4 Sep 2024 11:09:23 +0200 Subject: [PATCH 34/36] Cleanup tests --- .../JavaApplicationFunctionalTest.groovy | 12 ++++++ .../AbstractGraalVMMavenFunctionalTest.groovy | 41 ++++--------------- 2 files changed, 21 insertions(+), 32 deletions(-) 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 2b8aa6280..88b943bf2 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 @@ -131,4 +131,16 @@ class JavaApplicationFunctionalTest extends AbstractGraalVMMavenFunctionalTest { file("target/").listFiles().findAll(x->x.name.contains("native-image") && x.name.endsWith(".args")).size() == 1 } + def "can handle spaces when writing the args file"() { + withSpacesInProjectDir() + withSample("java-application") + + when: + mvn '-DquickBuild', '-Pnative', 'native:write-args-file' + + then: + buildSucceeded + outputContains "Args file written to: target" + File.separator + "native-image" + } + } 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 eea14f561..a02de1d93 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 @@ -43,24 +43,20 @@ package org.graalvm.buildtools.maven import org.eclipse.jetty.server.Server import org.eclipse.jetty.server.ServerConnector -import org.eclipse.jetty.server.SymlinkAllowedResourceAliasChecker import org.eclipse.jetty.server.handler.ContextHandler import org.eclipse.jetty.server.handler.ResourceHandler import spock.lang.Specification import spock.lang.TempDir -import java.nio.file.FileVisitResult import java.nio.file.Files import java.nio.file.Path -import java.nio.file.SimpleFileVisitor import java.nio.file.StandardCopyOption -import java.nio.file.attribute.BasicFileAttributes abstract class AbstractGraalVMMavenFunctionalTest extends Specification { - + @TempDir Path testDirectory - Path testOrigin; + Path testOrigin private IsolatedMavenExecutor executor @@ -69,18 +65,11 @@ abstract class AbstractGraalVMMavenFunctionalTest extends Specification { Server server ServerConnector connector - boolean IS_WINDOWS = System.getProperty("os.name", "unknown").contains("Windows"); - boolean IS_LINUX = System.getProperty("os.name", "unknown").contains("Linux"); - boolean IS_MAC = System.getProperty("os.name", "unknown").contains("Mac"); + boolean IS_WINDOWS = System.getProperty("os.name", "unknown").contains("Windows") + boolean IS_LINUX = System.getProperty("os.name", "unknown").contains("Linux") + boolean IS_MAC = System.getProperty("os.name", "unknown").contains("Mac") def setup() { - Path HomeDir = Path.of(System.getProperty("user.home")) - testDirectory = HomeDir.resolve("tests") - - if (Files.notExists(testDirectory)) { - Files.createDirectory(testDirectory) - } - executor = new IsolatedMavenExecutor( new File(System.getProperty("java.executable")), testDirectory.resolve("m2-home").toFile(), @@ -89,19 +78,6 @@ abstract class AbstractGraalVMMavenFunctionalTest extends Specification { } def cleanup() { - Files.walkFileTree(testDirectory, new SimpleFileVisitor() { - @Override - FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - Files.delete(file); - return FileVisitResult.CONTINUE; - } - @Override - FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { - Files.delete(dir); - return FileVisitResult.CONTINUE; - } - }); - if (server != null) { server.stop() server.destroy() @@ -177,12 +153,13 @@ abstract class AbstractGraalVMMavenFunctionalTest extends Specification { } void mvn(List args, Map systemProperties) { - System.out.println("Running copy of maven project `" + testOrigin + "` with " + args); + println("Running copy of maven project ${testOrigin} in ${testDirectory} 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 + "maven.repo.local": testDirectory.resolve("local-repo").toFile().absolutePath ] + println "Using local repo: ${resultingSystemProperties['maven.repo.local']}" resultingSystemProperties.putAll(systemProperties) result = executor.execute( @@ -192,7 +169,7 @@ abstract class AbstractGraalVMMavenFunctionalTest extends Specification { *args], new File(System.getProperty("maven.settings")) ) - System.out.println("Exit code is ${result.exitCode}") + println "Exit code is ${result.exitCode}" } From cdfcfa20574139d6bbf7f2ab7f7a2e0047d0c23e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20S=C3=A1nchez-Mariscal?= Date: Wed, 4 Sep 2024 11:59:51 +0200 Subject: [PATCH 35/36] Unit test code --- .../maven/AbstractNativeImageMojo.java | 20 ++++++++----- .../maven/AbstractNativeImageMojoTest.groovy | 30 +++++++++++++++++++ 2 files changed, 43 insertions(+), 7 deletions(-) create mode 100644 native-maven-plugin/src/test/groovy/org/graalvm/buildtools/maven/AbstractNativeImageMojoTest.groovy diff --git a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java index 339ae4a3a..35a09382b 100644 --- a/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java +++ b/native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/AbstractNativeImageMojo.java @@ -242,13 +242,7 @@ protected List getBuildArgs() throws MojoExecutionException { } if (buildArgs != null && !buildArgs.isEmpty()) { - for (String buildArg : buildArgs) { - if(buildArg.startsWith("\\Q") || buildArg.startsWith("-H")) { - cliArgs.add(buildArg); - continue; - } - cliArgs.addAll(Arrays.asList(buildArg.split("\\s+", 2))); - } + cliArgs.addAll(processBuildArgs(buildArgs)); } List actualCliArgs; @@ -266,6 +260,18 @@ protected List getBuildArgs() throws MojoExecutionException { return Collections.unmodifiableList(actualCliArgs); } + static List processBuildArgs(List buildArgs) { + var result = new ArrayList(); + for (String buildArg : buildArgs) { + if(buildArg.startsWith("\\Q") || buildArg.startsWith("-H:ConfigurationFileDirectories")) { + result.add(buildArg); + } else { + result.addAll(Arrays.asList(buildArg.split("\\s+", 2))); + } + } + return result; + } + protected Path processSupportedArtifacts(Artifact artifact) throws MojoExecutionException { return processArtifact(artifact, "jar", "test-jar", "war"); } diff --git a/native-maven-plugin/src/test/groovy/org/graalvm/buildtools/maven/AbstractNativeImageMojoTest.groovy b/native-maven-plugin/src/test/groovy/org/graalvm/buildtools/maven/AbstractNativeImageMojoTest.groovy new file mode 100644 index 000000000..dc2df79ce --- /dev/null +++ b/native-maven-plugin/src/test/groovy/org/graalvm/buildtools/maven/AbstractNativeImageMojoTest.groovy @@ -0,0 +1,30 @@ +package org.graalvm.buildtools.maven + +import spock.lang.Specification + +class AbstractNativeImageMojoTest extends Specification { + + void "it can process build args"() { + given: + def buildArgs = [ + "--exclude-config", + "\\QC:\\Users\\Lahoucine EL ADDALI\\.m2\\repository\\io\\netty\\netty-transport\\4.1.108.Final\\netty-transport-4.1.108.Final.jar\\E", + "^/META-INF/native-image/", + "-cp C:\\Users\\Lahoucine EL ADDALI\\Desktop\\outdir\\target/java-application-with-custom-packaging-0.1.jar", + "-H:ConfigurationFileDirectories=C:\\Users\\Lahoucine EL ADDALI\\Downloads\\4.5.0.0_kubernetes_kubernetes-demo-java-maven\\api\\target\\native\\generated\\generateResourceConfig" + ] + + when: + def processedArgs = AbstractNativeImageMojo.processBuildArgs(buildArgs) + + then: + processedArgs == [ + "--exclude-config", + "\\QC:\\Users\\Lahoucine EL ADDALI\\.m2\\repository\\io\\netty\\netty-transport\\4.1.108.Final\\netty-transport-4.1.108.Final.jar\\E", + "^/META-INF/native-image/", + "-cp", + "C:\\Users\\Lahoucine EL ADDALI\\Desktop\\outdir\\target/java-application-with-custom-packaging-0.1.jar", + "-H:ConfigurationFileDirectories=C:\\Users\\Lahoucine EL ADDALI\\Downloads\\4.5.0.0_kubernetes_kubernetes-demo-java-maven\\api\\target\\native\\generated\\generateResourceConfig" + ] + } +} From fff2f2a9ad8b33e9f60db4189681040953f9412a Mon Sep 17 00:00:00 2001 From: David Nestorovic Date: Wed, 4 Sep 2024 13:53:52 +0200 Subject: [PATCH 36/36] Bump repository version and update samples --- gradle/libs.versions.toml | 2 +- native-maven-plugin/reproducers/issue-144/pom.xml | 4 ++-- samples/java-application-with-custom-packaging/pom.xml | 2 +- samples/java-application-with-custom-tests/gradle.properties | 2 +- .../java-application-with-extra-sourceset/gradle.properties | 2 +- samples/java-application-with-reflection/gradle.properties | 2 +- samples/java-application-with-reflection/pom.xml | 4 ++-- samples/java-application-with-resources/gradle.properties | 2 +- samples/java-application-with-resources/pom.xml | 4 ++-- samples/java-application-with-tests/gradle.properties | 2 +- samples/java-application-with-tests/pom.xml | 4 ++-- samples/java-application/gradle.properties | 2 +- samples/java-application/pom.xml | 4 ++-- samples/java-library/gradle.properties | 2 +- samples/java-library/pom.xml | 4 ++-- samples/kotlin-application-with-tests/gradle.properties | 2 +- samples/metadata-repo-integration/gradle.properties | 2 +- samples/metadata-repo-integration/pom.xml | 4 ++-- samples/multi-project-with-tests/gradle.properties | 2 +- samples/multi-project-with-tests/pom.xml | 4 ++-- samples/native-config-integration/gradle.properties | 2 +- samples/native-config-integration/pom.xml | 4 ++-- 22 files changed, 31 insertions(+), 31 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a6f9882a1..1a7fad62a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] # Project versions -nativeBuildTools = "0.10.3-SNAPSHOT" +nativeBuildTools = "0.10.3" metadataRepository = "0.3.9" # External dependencies diff --git a/native-maven-plugin/reproducers/issue-144/pom.xml b/native-maven-plugin/reproducers/issue-144/pom.xml index 770ad3a54..c998b5f0c 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.10.3-SNAPSHOT - 0.10.3-SNAPSHOT + 0.10.3 + 0.10.3 example-app org.graalvm.demo.Application diff --git a/samples/java-application-with-custom-packaging/pom.xml b/samples/java-application-with-custom-packaging/pom.xml index 088de9e27..39a790bb7 100644 --- a/samples/java-application-with-custom-packaging/pom.xml +++ b/samples/java-application-with-custom-packaging/pom.xml @@ -61,7 +61,7 @@ 3.3.4 org.graalvm.demo.Application netty - 0.10.3-SNAPSHOT + 0.10.3 diff --git a/samples/java-application-with-custom-tests/gradle.properties b/samples/java-application-with-custom-tests/gradle.properties index 91743431e..fd386ef5d 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.10.3-SNAPSHOT +native.gradle.plugin.version = 0.10.3 junit.jupiter.version = 5.10.0 junit.platform.version = 1.10.0 diff --git a/samples/java-application-with-extra-sourceset/gradle.properties b/samples/java-application-with-extra-sourceset/gradle.properties index 91743431e..fd386ef5d 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.10.3-SNAPSHOT +native.gradle.plugin.version = 0.10.3 junit.jupiter.version = 5.10.0 junit.platform.version = 1.10.0 diff --git a/samples/java-application-with-reflection/gradle.properties b/samples/java-application-with-reflection/gradle.properties index 91743431e..fd386ef5d 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.10.3-SNAPSHOT +native.gradle.plugin.version = 0.10.3 junit.jupiter.version = 5.10.0 junit.platform.version = 1.10.0 diff --git a/samples/java-application-with-reflection/pom.xml b/samples/java-application-with-reflection/pom.xml index 80d08c102..a0c675aeb 100644 --- a/samples/java-application-with-reflection/pom.xml +++ b/samples/java-application-with-reflection/pom.xml @@ -52,8 +52,8 @@ 1.8 UTF-8 5.10.0 - 0.10.3-SNAPSHOT - 0.10.3-SNAPSHOT + 0.10.3 + 0.10.3 example-app org.graalvm.demo.Application diff --git a/samples/java-application-with-resources/gradle.properties b/samples/java-application-with-resources/gradle.properties index 91743431e..fd386ef5d 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.10.3-SNAPSHOT +native.gradle.plugin.version = 0.10.3 junit.jupiter.version = 5.10.0 junit.platform.version = 1.10.0 diff --git a/samples/java-application-with-resources/pom.xml b/samples/java-application-with-resources/pom.xml index 7d2b63625..cb11f0a2d 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.10.3-SNAPSHOT + 0.10.3 5.10.0 - 0.10.3-SNAPSHOT + 0.10.3 example-app org.graalvm.demo.Application diff --git a/samples/java-application-with-tests/gradle.properties b/samples/java-application-with-tests/gradle.properties index 91743431e..fd386ef5d 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.10.3-SNAPSHOT +native.gradle.plugin.version = 0.10.3 junit.jupiter.version = 5.10.0 junit.platform.version = 1.10.0 diff --git a/samples/java-application-with-tests/pom.xml b/samples/java-application-with-tests/pom.xml index ef0d75d8c..e276f1ad8 100644 --- a/samples/java-application-with-tests/pom.xml +++ b/samples/java-application-with-tests/pom.xml @@ -52,8 +52,8 @@ 1.8 UTF-8 5.10.0 - 0.10.3-SNAPSHOT - 0.10.3-SNAPSHOT + 0.10.3 + 0.10.3 example-app org.graalvm.demo.Application diff --git a/samples/java-application/gradle.properties b/samples/java-application/gradle.properties index 91743431e..fd386ef5d 100644 --- a/samples/java-application/gradle.properties +++ b/samples/java-application/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.10.3-SNAPSHOT +native.gradle.plugin.version = 0.10.3 junit.jupiter.version = 5.10.0 junit.platform.version = 1.10.0 diff --git a/samples/java-application/pom.xml b/samples/java-application/pom.xml index 9fda870d9..062faf43b 100644 --- a/samples/java-application/pom.xml +++ b/samples/java-application/pom.xml @@ -51,8 +51,8 @@ 1.8 UTF-8 - 0.10.3-SNAPSHOT - 0.10.3-SNAPSHOT + 0.10.3 + 0.10.3 example-app org.graalvm.demo.Application diff --git a/samples/java-library/gradle.properties b/samples/java-library/gradle.properties index 91743431e..fd386ef5d 100644 --- a/samples/java-library/gradle.properties +++ b/samples/java-library/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.10.3-SNAPSHOT +native.gradle.plugin.version = 0.10.3 junit.jupiter.version = 5.10.0 junit.platform.version = 1.10.0 diff --git a/samples/java-library/pom.xml b/samples/java-library/pom.xml index c763a9be0..adf9dc1cd 100644 --- a/samples/java-library/pom.xml +++ b/samples/java-library/pom.xml @@ -51,8 +51,8 @@ 1.8 UTF-8 - 0.10.3-SNAPSHOT - 0.10.3-SNAPSHOT + 0.10.3 + 0.10.3 java-library diff --git a/samples/kotlin-application-with-tests/gradle.properties b/samples/kotlin-application-with-tests/gradle.properties index 91743431e..fd386ef5d 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.10.3-SNAPSHOT +native.gradle.plugin.version = 0.10.3 junit.jupiter.version = 5.10.0 junit.platform.version = 1.10.0 diff --git a/samples/metadata-repo-integration/gradle.properties b/samples/metadata-repo-integration/gradle.properties index 7bbf5b7a8..5166f8fa7 100644 --- a/samples/metadata-repo-integration/gradle.properties +++ b/samples/metadata-repo-integration/gradle.properties @@ -1,4 +1,4 @@ -native.gradle.plugin.version = 0.10.3-SNAPSHOT +native.gradle.plugin.version = 0.10.3 h2.version = 2.2.220 netty.version = 4.1.80.Final logback.version = 1.4.4 diff --git a/samples/metadata-repo-integration/pom.xml b/samples/metadata-repo-integration/pom.xml index c17655d2e..7762e1a51 100644 --- a/samples/metadata-repo-integration/pom.xml +++ b/samples/metadata-repo-integration/pom.xml @@ -51,8 +51,8 @@ 1.8 UTF-8 - 0.10.3-SNAPSHOT - 0.10.3-SNAPSHOT + 0.10.3 + 0.10.3 2.2.220 4.1.80.Final 1.4.12 diff --git a/samples/multi-project-with-tests/gradle.properties b/samples/multi-project-with-tests/gradle.properties index 91743431e..fd386ef5d 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.10.3-SNAPSHOT +native.gradle.plugin.version = 0.10.3 junit.jupiter.version = 5.10.0 junit.platform.version = 1.10.0 diff --git a/samples/multi-project-with-tests/pom.xml b/samples/multi-project-with-tests/pom.xml index c0cec21c7..6023748ae 100644 --- a/samples/multi-project-with-tests/pom.xml +++ b/samples/multi-project-with-tests/pom.xml @@ -58,8 +58,8 @@ 1.8 UTF-8 5.10.0 - 0.10.3-SNAPSHOT - 0.10.3-SNAPSHOT + 0.10.3 + 0.10.3 example-app org.graalvm.demo.Application diff --git a/samples/native-config-integration/gradle.properties b/samples/native-config-integration/gradle.properties index 91743431e..fd386ef5d 100644 --- a/samples/native-config-integration/gradle.properties +++ b/samples/native-config-integration/gradle.properties @@ -1,3 +1,3 @@ -native.gradle.plugin.version = 0.10.3-SNAPSHOT +native.gradle.plugin.version = 0.10.3 junit.jupiter.version = 5.10.0 junit.platform.version = 1.10.0 diff --git a/samples/native-config-integration/pom.xml b/samples/native-config-integration/pom.xml index 48cb945e0..c3b55d4e3 100644 --- a/samples/native-config-integration/pom.xml +++ b/samples/native-config-integration/pom.xml @@ -51,8 +51,8 @@ 1.8 UTF-8 - 0.10.3-SNAPSHOT - 0.10.3-SNAPSHOT + 0.10.3 + 0.10.3 example-app org.graalvm.example.Application