diff --git a/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.17.aarch64 b/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.17.aarch64
new file mode 100644
index 000000000..09ad14ef9
--- /dev/null
+++ b/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.17.aarch64
@@ -0,0 +1,25 @@
+FROM public.ecr.aws/amazonlinux/amazonlinux:2023-minimal AS graalvm
+ENV LANG=en_US.UTF-8
+RUN dnf update -y && dnf install -y gcc glibc-devel zlib-devel libstdc++-static tar && dnf clean all && rm -rf /var/cache/dnf
+RUN curl -4 -L https://download.oracle.com/graalvm/17/archive/graalvm-jdk-17.0.12_linux-aarch64_bin.tar.gz -o /tmp/graalvm.tar.gz \
+ && mkdir -p /usr/lib/graalvm \
+ && tar -zxf /tmp/graalvm.tar.gz -C /usr/lib/graalvm --strip-components 1 \
+ && rm -rf /tmp/*
+ENV PATH="/usr/lib/graalvm/bin:${PATH}"
+WORKDIR /home/app
+COPY classes /home/app/classes
+COPY dependency/* /home/app/libs/
+COPY graalvm-reachability-metadat[a] /home/app/graalvm-reachability-metadata
+COPY nativ[e]/generated /home/app/
+COPY *.args /home/app/graalvm-native-image.args
+RUN native-image @/home/app/graalvm-native-image.args -H:Class=io.micronaut.function.aws.runtime.MicronautLambdaRuntime -H:Name=application -cp "/home/app/libs/*:/home/app/classes/"
+
+FROM public.ecr.aws/amazonlinux/amazonlinux:2023-minimal
+WORKDIR /function
+RUN dnf update -y && dnf install -y zip && dnf clean all
+COPY --from=graalvm /home/app/application /function/func
+RUN echo "#!/bin/sh" >> bootstrap && echo "set -euo pipefail" >> bootstrap && echo "./func -XX:MaximumHeapSizePercent=80 -Dio.netty.allocator.numDirectArenas=0 -Dio.netty.noPreferDirect=true -Djava.library.path=$(pwd)" >> bootstrap
+RUN chmod 777 bootstrap
+RUN chmod 777 func
+RUN zip -j function.zip bootstrap func
+ENTRYPOINT ["/function/func"]
diff --git a/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.17.amd64 b/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.17.amd64
new file mode 100644
index 000000000..f10bbfa97
--- /dev/null
+++ b/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.17.amd64
@@ -0,0 +1,25 @@
+FROM public.ecr.aws/amazonlinux/amazonlinux:2023-minimal AS graalvm
+ENV LANG=en_US.UTF-8
+RUN dnf update -y && dnf install -y gcc glibc-devel zlib-devel libstdc++-static tar && dnf clean all && rm -rf /var/cache/dnf
+RUN curl -4 -L https://download.oracle.com/graalvm/17/archive/graalvm-jdk-17.0.12_linux-x64_bin.tar.gz -o /tmp/graalvm.tar.gz \
+ && mkdir -p /usr/lib/graalvm \
+ && tar -zxf /tmp/graalvm.tar.gz -C /usr/lib/graalvm --strip-components 1 \
+ && rm -rf /tmp/*
+ENV PATH="/usr/lib/graalvm/bin:${PATH}"
+WORKDIR /home/app
+COPY classes /home/app/classes
+COPY dependency/* /home/app/libs/
+COPY graalvm-reachability-metadat[a] /home/app/graalvm-reachability-metadata
+COPY nativ[e]/generated /home/app/
+COPY *.args /home/app/graalvm-native-image.args
+RUN native-image @/home/app/graalvm-native-image.args -H:Class=io.micronaut.function.aws.runtime.MicronautLambdaRuntime -H:Name=application -cp "/home/app/libs/*:/home/app/classes/"
+
+FROM public.ecr.aws/amazonlinux/amazonlinux:2023-minimal
+WORKDIR /function
+RUN dnf update -y && dnf install -y zip && dnf clean all
+COPY --from=graalvm /home/app/application /function/func
+RUN echo "#!/bin/sh" >> bootstrap && echo "set -euo pipefail" >> bootstrap && echo "./func -XX:MaximumHeapSizePercent=80 -Dio.netty.allocator.numDirectArenas=0 -Dio.netty.noPreferDirect=true -Djava.library.path=$(pwd)" >> bootstrap
+RUN chmod 777 bootstrap
+RUN chmod 777 func
+RUN zip -j function.zip bootstrap func
+ENTRYPOINT ["/function/func"]
diff --git a/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.amd64 b/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.21.aarch64
similarity index 70%
rename from micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.amd64
rename to micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.21.aarch64
index 1d4e36335..75093c3a3 100644
--- a/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.amd64
+++ b/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.21.aarch64
@@ -1,7 +1,7 @@
-FROM amazonlinux:2023 AS graalvm
+FROM public.ecr.aws/amazonlinux/amazonlinux:2023-minimal AS graalvm
ENV LANG=en_US.UTF-8
-RUN yum update -y && yum install -y gcc gcc-c++ glibc-devel curl-minimal bash zlib zlib-devel zlib-static zip tar gzip && yum clean all && rm -rf /var/cache/yum
-RUN curl -4 -L https://download.oracle.com/graalvm/17/latest/graalvm-jdk-17_linux-x64_bin.tar.gz -o /tmp/graalvm.tar.gz \
+RUN dnf update -y && dnf install -y gcc glibc-devel zlib-devel libstdc++-static tar && dnf clean all && rm -rf /var/cache/dnf
+RUN curl -4 -L https://download.oracle.com/graalvm/21/latest/graalvm-jdk-21_linux-aarch64_bin.tar.gz -o /tmp/graalvm.tar.gz \
&& mkdir -p /usr/lib/graalvm \
&& tar -zxf /tmp/graalvm.tar.gz -C /usr/lib/graalvm --strip-components 1 \
&& rm -rf /tmp/*
@@ -14,9 +14,9 @@ COPY nativ[e]/generated /home/app/
COPY *.args /home/app/graalvm-native-image.args
RUN native-image @/home/app/graalvm-native-image.args -H:Class=io.micronaut.function.aws.runtime.MicronautLambdaRuntime -H:Name=application -cp "/home/app/libs/*:/home/app/classes/"
-FROM amazonlinux:2023
+FROM public.ecr.aws/amazonlinux/amazonlinux:2023-minimal
WORKDIR /function
-RUN yum update -y && yum install -y zip && yum clean all
+RUN dnf update -y && dnf install -y zip && dnf clean all
COPY --from=graalvm /home/app/application /function/func
RUN echo "#!/bin/sh" >> bootstrap && echo "set -euo pipefail" >> bootstrap && echo "./func -XX:MaximumHeapSizePercent=80 -Dio.netty.allocator.numDirectArenas=0 -Dio.netty.noPreferDirect=true -Djava.library.path=$(pwd)" >> bootstrap
RUN chmod 777 bootstrap
diff --git a/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.aarch64 b/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.21.amd64
similarity index 70%
rename from micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.aarch64
rename to micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.21.amd64
index 1f8383faa..13b985fdd 100644
--- a/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.aarch64
+++ b/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/Dockerfile.21.amd64
@@ -1,7 +1,7 @@
-FROM amazonlinux:2023 AS graalvm
+FROM public.ecr.aws/amazonlinux/amazonlinux:2023-minimal AS graalvm
ENV LANG=en_US.UTF-8
-RUN yum update -y && yum install -y gcc gcc-c++ glibc-devel curl-minimal bash zlib zlib-devel zlib-static zip tar gzip && yum clean all && rm -rf /var/cache/yum
-RUN curl -4 -L https://download.oracle.com/graalvm/17/latest/graalvm-jdk-17_linux-aarch64_bin.tar.gz -o /tmp/graalvm.tar.gz \
+RUN dnf update -y && dnf install -y gcc glibc-devel zlib-devel libstdc++-static tar && dnf clean all && rm -rf /var/cache/dnf
+RUN curl -4 -L https://download.oracle.com/graalvm/21/latest/graalvm-jdk-21_linux-x64_bin.tar.gz -o /tmp/graalvm.tar.gz \
&& mkdir -p /usr/lib/graalvm \
&& tar -zxf /tmp/graalvm.tar.gz -C /usr/lib/graalvm --strip-components 1 \
&& rm -rf /tmp/*
@@ -14,9 +14,9 @@ COPY nativ[e]/generated /home/app/
COPY *.args /home/app/graalvm-native-image.args
RUN native-image @/home/app/graalvm-native-image.args -H:Class=io.micronaut.function.aws.runtime.MicronautLambdaRuntime -H:Name=application -cp "/home/app/libs/*:/home/app/classes/"
-FROM amazonlinux:2023
+FROM public.ecr.aws/amazonlinux/amazonlinux:2023-minimal
WORKDIR /function
-RUN yum update -y && yum install -y zip && yum clean all
+RUN dnf update -y && dnf install -y zip && dnf clean all
COPY --from=graalvm /home/app/application /function/func
RUN echo "#!/bin/sh" >> bootstrap && echo "set -euo pipefail" >> bootstrap && echo "./func -XX:MaximumHeapSizePercent=80 -Dio.netty.allocator.numDirectArenas=0 -Dio.netty.noPreferDirect=true -Djava.library.path=$(pwd)" >> bootstrap
RUN chmod 777 bootstrap
diff --git a/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/verify.groovy b/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/verify.groovy
index 8ef82edda..5e3c3024e 100644
--- a/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/verify.groovy
+++ b/micronaut-maven-integration-tests/src/it/dockerfile-docker-native-lambda/verify.groovy
@@ -1,9 +1,3 @@
-File dockerfile = new File("$basedir/target", "Dockerfile")
-File expectedDockerfile = new File(basedir, "Dockerfile.${graalVmArch()}")
-String expectedDockerfileText = expectedDockerfile.text.replace("17", "${System.getProperty("java.specification.version")}")
-
-assert dockerfile.text == expectedDockerfileText
-
static String graalVmArch() {
String osArch = System.getProperty("os.arch")
if ("aarch64".equals(osArch)) {
@@ -13,6 +7,11 @@ static String graalVmArch() {
}
}
+File dockerfile = new File("$basedir/target", "Dockerfile")
+File expectedDockerfile = new File(basedir, "Dockerfile.${System.getProperty("java.specification.version")}.${graalVmArch()}")
+
+assert dockerfile.text == expectedDockerfile.text
+
File log = new File(basedir, 'build.log')
assert log.exists()
assert log.text.contains("Copying /function/function.zip")
\ No newline at end of file
diff --git a/micronaut-maven-plugin/pom.xml b/micronaut-maven-plugin/pom.xml
index 6859b7c7d..aa73ad0c4 100644
--- a/micronaut-maven-plugin/pom.xml
+++ b/micronaut-maven-plugin/pom.xml
@@ -123,6 +123,12 @@
5.12.0
test
+
+ org.junit-pioneer
+ junit-pioneer
+ 2.3.0
+ test
+
diff --git a/micronaut-maven-plugin/src/main/java/io/micronaut/maven/AbstractDockerMojo.java b/micronaut-maven-plugin/src/main/java/io/micronaut/maven/AbstractDockerMojo.java
index c79b83b78..784d73080 100644
--- a/micronaut-maven-plugin/src/main/java/io/micronaut/maven/AbstractDockerMojo.java
+++ b/micronaut-maven-plugin/src/main/java/io/micronaut/maven/AbstractDockerMojo.java
@@ -61,6 +61,10 @@ public abstract class AbstractDockerMojo extends AbstractMicronautMojo {
public static final String X86_64_ARCH = "x64";
public static final String DEFAULT_ORACLE_LINUX_VERSION = "ol9";
public static final String ORACLE_CLOUD_FUNCTION_DEFAULT_CMD = "CMD [\"io.micronaut.oraclecloud.function.http.HttpFunction::handleRequest\"]";
+ public static final String GRAALVM_DOWNLOAD_URL = "https://download.oracle.com/graalvm/%s/%s/graalvm-jdk-%s_linux-%s_bin.tar.gz";
+
+ //Latest version of GraalVM for JDK 17 available under the GraalVM Free Terms and Conditions (GFTC) licence
+ public static final String GRAALVM_FOR_JDK17 = "17.0.12";
protected final MavenProject mavenProject;
protected final JibConfigurationService jibConfigurationService;
@@ -145,18 +149,21 @@ protected ArtifactVersion javaVersion() {
}
/**
- * @return the GraalVM version from the graalvm.version
property, which is expected to come from the
- * Micronaut Parent POM.
+ * @return the JVM version to use for GraalVM.
*/
- protected String graalVmVersion() {
- return mavenProject.getProperties().getProperty("graal.version");
+ protected String graalVmJvmVersion() {
+ return javaVersion().getMajorVersion() == 17 ? "17" : "21";
}
/**
- * @return the JVM version to use for GraalVM.
+ * @return the GraalVM download URL depending on the Java version.
*/
- protected String graalVmJvmVersion() {
- return javaVersion().getMajorVersion() == 17 ? "17" : "21";
+ protected String graalVmDownloadUrl() {
+ if (javaVersion().getMajorVersion() == 17) {
+ return GRAALVM_DOWNLOAD_URL.formatted(17, "archive", GRAALVM_FOR_JDK17, graalVmArch());
+ } else {
+ return GRAALVM_DOWNLOAD_URL.formatted(21, "latest", 21, graalVmArch());
+ }
}
/**
diff --git a/micronaut-maven-plugin/src/main/java/io/micronaut/maven/DockerNativeMojo.java b/micronaut-maven-plugin/src/main/java/io/micronaut/maven/DockerNativeMojo.java
index 640127885..08a793e92 100644
--- a/micronaut-maven-plugin/src/main/java/io/micronaut/maven/DockerNativeMojo.java
+++ b/micronaut-maven-plugin/src/main/java/io/micronaut/maven/DockerNativeMojo.java
@@ -148,19 +148,13 @@ private void checkJavaVersion(int maxAllowedVersion) throws MojoExecutionExcepti
private void buildDockerNativeLambda() throws IOException {
var buildImageCmdArguments = new HashMap();
- getLog().info("Using GRAALVM_JVM_VERSION: " + graalVmJvmVersion());
- getLog().info("Using GRAALVM_ARCH: " + graalVmArch());
-
// Starter sets the right class in pom.xml:
// - For applications: io.micronaut.function.aws.runtime.MicronautLambdaRuntime
// - For function apps: com.example.BookLambdaRuntime
- getLog().info("Using CLASS_NAME: " + mainClass);
BuildImageCmd buildImageCmd = addNativeImageBuildArgs(buildImageCmdArguments, () -> {
try {
return dockerService.buildImageCmd(DockerfileMojo.DOCKERFILE_AWS_CUSTOM_RUNTIME)
- .withBuildArg("GRAALVM_VERSION", graalVmVersion())
- .withBuildArg("GRAALVM_JVM_VERSION", graalVmJvmVersion())
- .withBuildArg("GRAALVM_ARCH", graalVmArch());
+ .withBuildArg("GRAALVM_DOWNLOAD_URL", graalVmDownloadUrl());
} catch (IOException e) {
throw new DockerClientException(e.getMessage(), e);
}
@@ -204,7 +198,6 @@ private void buildDockerfile(String dockerfileName, boolean passClassName) throw
var buildImageCmdArguments = new HashMap();
- getLog().info("Using BASE_IMAGE: " + from);
if (StringUtils.isNotEmpty(baseImageRun) && Boolean.FALSE.equals(staticNativeImage)) {
buildImageCmdArguments.put("BASE_IMAGE_RUN", baseImageRun);
}
@@ -235,10 +228,7 @@ private BuildImageCmd addNativeImageBuildArgs(Map buildImageCmdA
BuildImageCmd buildImageCmd = buildImageCmdSupplier.get();
for (Map.Entry buildArg : buildImageCmdArguments.entrySet()) {
- String key = buildArg.getKey();
- String value = buildArg.getValue();
- getLog().info("Using " + key + ": " + value);
- buildImageCmd.withBuildArg(key, value);
+ buildImageCmd.withBuildArg(buildArg.getKey(), buildArg.getValue());
}
getNetworkMode().ifPresent(buildImageCmd::withNetworkMode);
diff --git a/micronaut-maven-plugin/src/main/java/io/micronaut/maven/DockerfileMojo.java b/micronaut-maven-plugin/src/main/java/io/micronaut/maven/DockerfileMojo.java
index b3cffc60a..6649a47db 100644
--- a/micronaut-maven-plugin/src/main/java/io/micronaut/maven/DockerfileMojo.java
+++ b/micronaut-maven-plugin/src/main/java/io/micronaut/maven/DockerfileMojo.java
@@ -19,7 +19,6 @@
import io.micronaut.maven.jib.JibConfigurationService;
import io.micronaut.maven.jib.JibMicronautExtension;
import io.micronaut.maven.services.ApplicationConfigurationService;
-import io.micronaut.maven.services.CompilerService;
import io.micronaut.maven.services.DockerService;
import io.micronaut.maven.services.ExecutorService;
import org.apache.maven.execution.MavenSession;
@@ -74,15 +73,13 @@ public class DockerfileMojo extends AbstractDockerMojo {
public static final String NATIVE_BUILD_TOOLS_MAVEN_PLUGIN = "org.graalvm.buildtools:native-maven-plugin";
private final ExecutorService executorService;
- private final CompilerService compilerService;
@Inject
public DockerfileMojo(MavenProject mavenProject, DockerService dockerService, JibConfigurationService jibConfigurationService,
ApplicationConfigurationService applicationConfigurationService, ExecutorService executorService,
- MavenSession mavenSession, MojoExecution mojoExecution, CompilerService compilerService) {
+ MavenSession mavenSession, MojoExecution mojoExecution) {
super(mavenProject, jibConfigurationService, applicationConfigurationService, dockerService, mavenSession, mojoExecution);
this.executorService = executorService;
- this.compilerService = compilerService;
}
@Override
@@ -190,7 +187,6 @@ private void processDockerfile(File dockerfile) throws IOException {
if (dockerfile != null) {
var allLines = Files.readAllLines(dockerfile.toPath());
var result = new ArrayList();
-
for (String line : allLines) {
if (!line.startsWith("ARG")) {
if (line.contains("BASE_IMAGE_RUN")) {
@@ -199,12 +195,10 @@ private void processDockerfile(File dockerfile) throws IOException {
result.add(line.replace("${BASE_IMAGE}", getFrom()));
} else if (line.contains("BASE_JAVA_IMAGE")) {
result.add(line.replace("${BASE_JAVA_IMAGE}", getBaseImage()));
- } else if (line.contains("GRAALVM_") || line.contains("CLASS_NAME")) {
- result.add(line
- .replace("${GRAALVM_JVM_VERSION}", graalVmJvmVersion())
- .replace("${GRAALVM_ARCH}", graalVmArch())
- .replace("${CLASS_NAME}", mainClass)
- );
+ } else if (line.contains("GRAALVM_DOWNLOAD_URL")) {
+ result.add(line.replace("${GRAALVM_DOWNLOAD_URL}", graalVmDownloadUrl()));
+ } else if (line.contains("CLASS_NAME")) {
+ result.add(line.replace("${CLASS_NAME}", mainClass));
} else if (line.contains("PORT")) {
result.add(line.replace("${PORT}", getPort()));
} else {
diff --git a/micronaut-maven-plugin/src/main/java/io/micronaut/maven/services/DockerService.java b/micronaut-maven-plugin/src/main/java/io/micronaut/maven/services/DockerService.java
index 02bbea5dc..b08427a21 100644
--- a/micronaut-maven-plugin/src/main/java/io/micronaut/maven/services/DockerService.java
+++ b/micronaut-maven-plugin/src/main/java/io/micronaut/maven/services/DockerService.java
@@ -131,6 +131,9 @@ public BuildImageCmd buildImageCmd() {
*/
public String buildImage(BuildImageCmd builder) {
verifyDockerRunning();
+ if (builder.getBuildArgs() != null) {
+ builder.getBuildArgs().forEach((k, v) -> LOG.info("Using {}: {}", k, v));
+ }
BuildImageResultCallback resultCallback = new BuildImageResultCallback() {
@Override
public void onNext(BuildResponseItem item) {
diff --git a/micronaut-maven-plugin/src/main/resources/dockerfiles/DockerfileNativeLambda b/micronaut-maven-plugin/src/main/resources/dockerfiles/DockerfileNativeLambda
index 37e219906..e5746f970 100644
--- a/micronaut-maven-plugin/src/main/resources/dockerfiles/DockerfileNativeLambda
+++ b/micronaut-maven-plugin/src/main/resources/dockerfiles/DockerfileNativeLambda
@@ -1,9 +1,8 @@
-FROM amazonlinux:2023 AS graalvm
+FROM public.ecr.aws/amazonlinux/amazonlinux:2023-minimal AS graalvm
ENV LANG=en_US.UTF-8
-ARG GRAALVM_JVM_VERSION
-ARG GRAALVM_ARCH
-RUN yum update -y && yum install -y gcc gcc-c++ glibc-devel curl-minimal bash zlib zlib-devel zlib-static zip tar gzip && yum clean all && rm -rf /var/cache/yum
-RUN curl -4 -L https://download.oracle.com/graalvm/${GRAALVM_JVM_VERSION}/latest/graalvm-jdk-${GRAALVM_JVM_VERSION}_linux-${GRAALVM_ARCH}_bin.tar.gz -o /tmp/graalvm.tar.gz \
+RUN dnf update -y && dnf install -y gcc glibc-devel zlib-devel libstdc++-static tar && dnf clean all && rm -rf /var/cache/dnf
+ARG GRAALVM_DOWNLOAD_URL
+RUN curl -4 -L ${GRAALVM_DOWNLOAD_URL} -o /tmp/graalvm.tar.gz \
&& mkdir -p /usr/lib/graalvm \
&& tar -zxf /tmp/graalvm.tar.gz -C /usr/lib/graalvm --strip-components 1 \
&& rm -rf /tmp/*
@@ -17,9 +16,9 @@ COPY *.args /home/app/graalvm-native-image.args
ARG CLASS_NAME
RUN native-image @/home/app/graalvm-native-image.args -H:Class=${CLASS_NAME} -H:Name=application -cp "/home/app/libs/*:/home/app/classes/"
-FROM amazonlinux:2023
+FROM public.ecr.aws/amazonlinux/amazonlinux:2023-minimal
WORKDIR /function
-RUN yum update -y && yum install -y zip && yum clean all
+RUN dnf update -y && dnf install -y zip && dnf clean all
COPY --from=graalvm /home/app/application /function/func
RUN echo "#!/bin/sh" >> bootstrap && echo "set -euo pipefail" >> bootstrap && echo "./func -XX:MaximumHeapSizePercent=80 -Dio.netty.allocator.numDirectArenas=0 -Dio.netty.noPreferDirect=true -Djava.library.path=$(pwd)" >> bootstrap
RUN chmod 777 bootstrap
diff --git a/micronaut-maven-plugin/src/test/java/io/micronaut/maven/DockerNativeMojoTest.java b/micronaut-maven-plugin/src/test/java/io/micronaut/maven/DockerNativeMojoTest.java
new file mode 100644
index 000000000..20b332697
--- /dev/null
+++ b/micronaut-maven-plugin/src/test/java/io/micronaut/maven/DockerNativeMojoTest.java
@@ -0,0 +1,60 @@
+package io.micronaut.maven;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.project.MavenProject;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+import org.junitpioneer.jupiter.RestoreSystemProperties;
+import org.junitpioneer.jupiter.SetSystemProperty;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.util.Properties;
+
+import static io.micronaut.maven.AbstractDockerMojo.X86_64_ARCH;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@RestoreSystemProperties
+class DockerNativeMojoTest {
+
+ @ParameterizedTest
+ @CsvSource({
+ "17,https://download.oracle.com/graalvm/17/archive/graalvm-jdk-17.0.12_linux-x64_bin.tar.gz",
+ "21,https://download.oracle.com/graalvm/21/latest/graalvm-jdk-21_linux-x64_bin.tar.gz"
+ })
+ @SetSystemProperty(key = "os.arch", value = X86_64_ARCH)
+ void testGraalVmDownloadUrl(String javaVersion, String expectedUrl) throws URISyntaxException, IOException, InterruptedException {
+ var project = mock(MavenProject.class);
+ var session = mock(MavenSession.class);
+ var execution = mock(MojoExecution.class);
+ var properties = new Properties(1);
+ properties.put("maven.compiler.target", javaVersion);
+
+ when(session.getCurrentProject()).thenReturn(project);
+ when(session.getUserProperties()).thenReturn(new Properties());
+ when(session.getSystemProperties()).thenReturn(new Properties());
+ when(project.getProperties()).thenReturn(properties);
+
+ var mojo = new DockerNativeMojo(project, null, null, null, session, execution);
+
+ var actualUrl = mojo.graalVmDownloadUrl();
+
+ assertEquals(expectedUrl, actualUrl);
+
+ var client = HttpClient.newHttpClient();
+ var request = HttpRequest.newBuilder()
+ .uri(new URI(actualUrl))
+ .method("HEAD", HttpRequest.BodyPublishers.noBody())
+ .build();
+ var response = client.send(request, HttpResponse.BodyHandlers.discarding());
+
+ assertEquals(200, response.statusCode());
+ }
+}