diff --git a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/GraalVM.java b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/GraalVM.java index d2c4a15725048f..f506dfd1b8b004 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/GraalVM.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/GraalVM.java @@ -1,5 +1,6 @@ package io.quarkus.deployment.pkg.steps; +import java.util.Arrays; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -138,10 +139,11 @@ public static final class Version implements Comparable { public static final int UNDEFINED = -1; final String fullVersion; - final org.graalvm.home.Version version; public final int javaFeatureVersion; public final int javaUpdateVersion; final Distribution distribution; + private int[] versions; + private String suffix; Version(String fullVersion, String version, Distribution distro) { this(fullVersion, version, 11, UNDEFINED, distro); @@ -149,12 +151,21 @@ public static final class Version implements Comparable { Version(String fullVersion, String version, int javaFeatureVersion, int javaUpdateVersion, Distribution distro) { this.fullVersion = fullVersion; - this.version = org.graalvm.home.Version.parse(version); + breakdownVersion(version); this.javaFeatureVersion = javaFeatureVersion; this.javaUpdateVersion = javaUpdateVersion; this.distribution = distro; } + private void breakdownVersion(String version) { + int dash = version.indexOf('-'); + if (dash != -1) { + this.suffix = version.substring(dash + 1); + version = version.substring(0, dash); + } + this.versions = Arrays.stream(version.split("\\.")).mapToInt(Integer::parseInt).toArray(); + } + String getFullVersion() { return fullVersion; } @@ -189,11 +200,27 @@ boolean is(Version version) { @Override public int compareTo(Version o) { - return this.version.compareTo(o.version); + int i = 0; + for (; i < this.versions.length; i++) { + if (i >= o.versions.length) { + if (this.versions[i] != 0) { + return 1; + } + } else if (this.versions[i] != o.versions[i]) { + return this.versions[i] - o.versions[i]; + } + } + for (; i < o.versions.length; i++) { + if (o.versions[i] != 0) { + return -1; + } + } + return 0; } - static Version of(Stream output) { - List lines = output + public static Version of(Stream output) { + String stringOutput = output.collect(Collectors.joining("\n")); + List lines = stringOutput.lines() .dropWhile(l -> !l.startsWith("GraalVM") && !l.startsWith("native-image")) .collect(Collectors.toUnmodifiableList()); @@ -227,17 +254,26 @@ static Version of(Stream output) { } throw new IllegalArgumentException( - "Cannot parse version from output: " + output.collect(Collectors.joining("\n"))); + "Cannot parse version from output: \n" + stringOutput); } private static boolean isMandrel(String s) { return s != null && s.contains("Mandrel Distribution"); } + /** + * Returns the Mandrel/GraalVM version as a string. e.g. 21.3.0-rc1 + */ + public String getVersionAsString() { + return String.join(Arrays.stream(versions).mapToObj(Integer::toString).collect(Collectors.joining()), ".") + "-" + + suffix; + } + @Override public String toString() { return "Version{" + - "version=" + version + + "version=" + + getVersionAsString() + ", fullVersion=" + fullVersion + ", distribution=" + distribution + ", javaFeatureVersion=" + javaFeatureVersion + diff --git a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildStep.java b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildStep.java index a180c416e09c47..6429997c3223c9 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildStep.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildStep.java @@ -147,7 +147,7 @@ ArtifactResultBuildItem nativeSourcesResult(NativeConfig nativeConfig, try { Files.writeString(outputDir.resolve("native-image.args"), String.join(" ", command)); - Files.writeString(outputDir.resolve("graalvm.version"), GraalVM.Version.CURRENT.version.toString()); + Files.writeString(outputDir.resolve("graalvm.version"), GraalVM.Version.CURRENT.getVersionAsString()); if (nativeImageRunner.isContainerBuild()) { Files.writeString(outputDir.resolve("native-builder.image"), nativeConfig.builderImage().getEffectiveImage()); } @@ -297,7 +297,7 @@ public NativeImageBuildItem build(NativeConfig nativeConfig, LocalesBuildTimeCon return new NativeImageBuildItem(finalExecutablePath, new NativeImageBuildItem.GraalVMVersion(graalVMVersion.fullVersion, - graalVMVersion.version.toString(), + graalVMVersion.getVersionAsString(), graalVMVersion.javaFeatureVersion, graalVMVersion.distribution.name())); } catch (ImageGenerationFailureException e) { @@ -462,7 +462,7 @@ private void checkGraalVMVersion(GraalVM.Version version) { log.info("Running Quarkus native-image plugin on " + version.getFullVersion()); if (version.isObsolete()) { throw new IllegalStateException("Out of date version of GraalVM detected: " + version.getFullVersion() + "." - + " Quarkus currently supports " + GraalVM.Version.CURRENT.version + + " Quarkus currently supports " + GraalVM.Version.CURRENT.getVersionAsString() + ". Please upgrade GraalVM to this version."); } } diff --git a/core/deployment/src/test/java/io/quarkus/deployment/pkg/steps/GraalVMTest.java b/core/deployment/src/test/java/io/quarkus/deployment/pkg/steps/GraalVMTest.java index e1692954aee862..d8ee390aa4ff07 100644 --- a/core/deployment/src/test/java/io/quarkus/deployment/pkg/steps/GraalVMTest.java +++ b/core/deployment/src/test/java/io/quarkus/deployment/pkg/steps/GraalVMTest.java @@ -19,20 +19,20 @@ public class GraalVMTest { @Test public void testGraalVMVersionDetected() { // Version detection after: https://github.com/oracle/graal/pull/6302 (3 lines of version output) - assertVersion(org.graalvm.home.Version.create(23, 0, 0), MANDREL, + assertVersion(new Version("GraalVM 23.0.0", "23.0.0", ORACLE), MANDREL, Version.of(Stream.of(("native-image 17.0.6 2023-01-17\n" + "OpenJDK Runtime Environment Mandrel-23.0.0-dev (build 17.0.6+10)\n" + "OpenJDK 64-Bit Server VM Mandrel-23.0.0-dev (build 17.0.6+10, mixed mode)").split("\\n")))); - assertVersion(org.graalvm.home.Version.create(23, 0, 0), MANDREL, + assertVersion(new Version("GraalVM 23.0.0", "23.0.0", ORACLE), MANDREL, Version.of(Stream.of(("native-image 17.0.6 2023-01-17\n" + "GraalVM Runtime Environment Mandrel-23.0.0-dev (build 17.0.6+10)\n" + "Substrate VM Mandrel-23.0.0-dev (build 17.0.6+10, serial gc)").split("\\n")))); - assertVersion(org.graalvm.home.Version.create(23, 0, 0), MANDREL, + assertVersion(new Version("GraalVM 23.0.0", "23.0.0", ORACLE), MANDREL, Version.of(Stream.of(("native-image 17.0.7 2023-04-18\n" + "OpenJDK Runtime Environment Mandrel-23.0.0.0-Final (build 17.0.7+7)\n" + "OpenJDK 64-Bit Server VM Mandrel-23.0.0.0-Final (build 17.0.7+7, mixed mode)").split("\\n")))); // should also work when the image is not around and we have to download it - assertVersion(org.graalvm.home.Version.create(23, 0, 0), MANDREL, + assertVersion(new Version("GraalVM 23.0.0", "23.0.0", ORACLE), MANDREL, Version.of( Stream.of(("Unable to find image 'quay.io/quarkus/ubi-quarkus-mandrel-builder-image:jdk-17' locally\n" + "jdk-17: Pulling from quarkus/ubi-quarkus-mandrel-builder-image\n" @@ -57,36 +57,36 @@ public void testGraalVMVersionDetected() { + "OpenJDK Runtime Environment Mandrel-23.0.0.0-Final (build 17.0.7+7)\n" + "OpenJDK 64-Bit Server VM Mandrel-23.0.0.0-Final (build 17.0.7+7, mixed mode)") .split("\\n")))); - assertVersion(org.graalvm.home.Version.create(23, 0), ORACLE, + assertVersion(new Version("GraalVM 23.0", "23.0", ORACLE), ORACLE, Version.of(Stream.of(("native-image 20 2023-03-21\n" + "GraalVM Runtime Environment GraalVM CE (build 20+34-jvmci-23.0-b10)\n" + "Substrate VM GraalVM CE (build 20+34, serial gc)").split("\\n")))); // Older version parsing - assertVersion(org.graalvm.home.Version.create(20, 1), ORACLE, + assertVersion(new Version("GraalVM 20.1", "20.1", ORACLE), ORACLE, Version.of(Stream.of("GraalVM Version 20.1.0 (Java Version 11.0.7)"))); - assertVersion(org.graalvm.home.Version.create(20, 1, 0, 1), MANDREL, Version + assertVersion(new Version("GraalVM 20.1.0.1", "20.1.0.1", ORACLE), MANDREL, Version .of(Stream.of("GraalVM Version 20.1.0.1.Alpha2 56d4ee1b28 (Mandrel Distribution) (Java Version 11.0.8)"))); - assertVersion(org.graalvm.home.Version.create(20, 1, 0, 1), MANDREL, Version + assertVersion(new Version("GraalVM 20.1.0.1", "20.1.0.1", ORACLE), MANDREL, Version .of(Stream.of("GraalVM Version 20.1.0.1-Final 56d4ee1b28 (Mandrel Distribution) (Java Version 11.0.8)"))); - assertVersion(org.graalvm.home.Version.create(21, 0), MANDREL, Version + assertVersion(new Version("GraalVM 21.0", "21.0", ORACLE), MANDREL, Version .of(Stream.of("GraalVM Version 21.0.0.0-0b3 (Mandrel Distribution) (Java Version 11.0.8)"))); - assertVersion(org.graalvm.home.Version.create(20, 3, 1, 2), MANDREL, Version + assertVersion(new Version("GraalVM 20.3.1.2", "20.3.1.2", ORACLE), MANDREL, Version .of(Stream.of("GraalVM Version 20.3.1.2-dev (Mandrel Distribution) (Java Version 11.0.8)"))); - assertVersion(org.graalvm.home.Version.create(21, 1), MANDREL, Version + assertVersion(new Version("GraalVM 21.1", "21.1", ORACLE), MANDREL, Version .of(Stream.of("native-image 21.1.0.0-Final (Mandrel Distribution) (Java Version 11.0.11+9)"))); - assertVersion(org.graalvm.home.Version.create(21, 1), MANDREL, Version + assertVersion(new Version("GraalVM 21.1", "21.1", ORACLE), MANDREL, Version .of(Stream.of("GraalVM 21.1.0.0-Final (Mandrel Distribution) (Java Version 11.0.11+9)"))); - assertVersion(org.graalvm.home.Version.create(21, 1), ORACLE, Version + assertVersion(new Version("GraalVM 21.1", "21.1", ORACLE), ORACLE, Version .of(Stream.of("GraalVM 21.1.0 Java 11 CE (Java Version 11.0.11+5-jvmci-21.1-b02)"))); - assertVersion(org.graalvm.home.Version.create(21, 1), ORACLE, Version + assertVersion(new Version("GraalVM 21.1", "21.1", ORACLE), ORACLE, Version .of(Stream.of("native-image 21.1.0.0 Java 11 CE (Java Version 11.0.11+5-jvmci-21.1-b02)"))); - assertVersion(org.graalvm.home.Version.create(21, 2), MANDREL, Version + assertVersion(new Version("GraalVM 21.2", "21.2", ORACLE), MANDREL, Version .of(Stream.of("native-image 21.2.0.0-Final Mandrel Distribution (Java Version 11.0.12+7)"))); } - static void assertVersion(org.graalvm.home.Version graalVmVersion, Distribution distro, Version version) { - assertThat(graalVmVersion.compareTo(version.version)).isEqualTo(0); + static void assertVersion(Version graalVmVersion, Distribution distro, Version version) { + assertThat(graalVmVersion.compareTo(version)).isEqualTo(0); assertThat(version.distribution).isEqualTo(distro); if (distro == MANDREL) { assertThat(version.isMandrel()).isTrue(); @@ -99,6 +99,18 @@ public void testGraalVMVersionsOlderThan() { assertOlderThan("GraalVM Version 20.0.0 (Java Version 11.0.7)", "GraalVM Version 20.1.0 (Java Version 11.0.8)"); assertOlderThan("GraalVM Version 21.2.0 (Java Version 11.0.12)", Version.VERSION_21_3); assertOlderThan("GraalVM Version 21.2.0 (Java Version 11.0.12)", Version.VERSION_21_3_0); + assertOlderThan("native-image 21 2023-09-19\n" + + "GraalVM Runtime Environment GraalVM CE 21+35.1 (build 21+35-jvmci-23.1-b15)\n" + + "Substrate VM GraalVM CE 21+35.1 (build 21+35, serial gc)\n", + "native-image 21-beta 2023-09-19\n" + + "OpenJDK Runtime Environment Mandrel-23.1.0.1-devde078ae3bea (build 21-beta+35-ea)\n" + + "OpenJDK 64-Bit Server VM Mandrel-23.1.0.1-devde078ae3bea (build 21-beta+35-ea, mixed mode)"); + assertOlderThan("native-image 21-beta 2023-09-19\n" + + "OpenJDK Runtime Environment Mandrel-23.0.0.1-devde078ae3bea (build 21-beta+35-ea)\n" + + "OpenJDK 64-Bit Server VM Mandrel-23.0.0.1-devde078ae3bea (build 21-beta+35-ea, mixed mode)", + "native-image 21 2023-09-19\n" + + "GraalVM Runtime Environment GraalVM CE 21+35.1 (build 21+35-jvmci-23.1-b15)\n" + + "Substrate VM GraalVM CE 21+35.1 (build 21+35, serial gc)\n"); } /** @@ -126,17 +138,24 @@ public void testGraalVMVersionsCompareEqualTo() { assertCompareEqualTo("GraalVM 21.3.0 Java 11 CE (Java Version 11.0.13+7-jvmci-21.3-b05)", "GraalVM 21.3.0.0.0.0 Java 11 CE (Java Version 11.0.13+7-jvmci-21.3-b05)"); assertThat(Version.VERSION_21_3.compareTo(Version.VERSION_21_3_0)).isEqualTo(0); + assertCompareEqualTo("native-image 21-beta 2023-09-19\n" + + "OpenJDK Runtime Environment Mandrel-23.1.0.0-devde078ae3bea (build 21-beta+35-ea)\n" + + "OpenJDK 64-Bit Server VM Mandrel-23.1.0.0-devde078ae3bea (build 21-beta+35-ea, mixed mode)", + "native-image 21 2023-09-19\n" + + "GraalVM Runtime Environment GraalVM CE 21+35.1 (build 21+35-jvmci-23.1-b15)\n" + + "Substrate VM GraalVM CE 21+35.1 (build 21+35, serial gc)\n"); } /** * Asserts that version is equals to other when compared. */ static void assertCompareEqualTo(String version, String other) { - assertThat(Version.of(Stream.of(version)).compareTo(Version.of(Stream.of(other)))).isEqualTo(0); + assertThat(Version.of(Stream.of(version.split("\\n"))).compareTo(Version.of(Stream.of(other.split("\\n"))))) + .isEqualTo(0); } static void assertCompareNotEqualTo(String version, String other) { - assertThat(Version.of(Stream.of(version)).compareTo(Version.of(Stream.of(other)))).isNotEqualTo(0); + assertThat(Version.of(Stream.of(version)).compareTo(Version.of(Stream.of(other.split("\\n"))))).isNotEqualTo(0); } @Test @@ -150,6 +169,18 @@ public void testGraalVMVersionsNewerThan() { "GraalVM 21.3 Java 11 CE (Java Version 11.0.13+7-jvmci-21.3-b05)"); assertNewerThan("native-image 22.3.0-dev6d51160e2f3 Mandrel Distribution (Java Version 17.0.4-beta+7-202206162318)", "native-image 22.2.0-dev6d51160e2f3 Mandrel Distribution (Java Version 17.0.4-beta+7-202206162318)"); + assertNewerThan("native-image 21-beta 2023-09-19\n" + + "OpenJDK Runtime Environment Mandrel-23.1.0.1-devde078ae3bea (build 21-beta+35-ea)\n" + + "OpenJDK 64-Bit Server VM Mandrel-23.1.0.1-devde078ae3bea (build 21-beta+35-ea, mixed mode)", + "native-image 21 2023-09-19\n" + + "GraalVM Runtime Environment GraalVM CE 21+35.1 (build 21+35-jvmci-23.1-b15)\n" + + "Substrate VM GraalVM CE 21+35.1 (build 21+35, serial gc)\n"); + assertNewerThan("native-image 21 2023-09-19\n" + + "GraalVM Runtime Environment GraalVM CE 21+35.1 (build 21+35-jvmci-23.1-b15)\n" + + "Substrate VM GraalVM CE 21+35.1 (build 21+35, serial gc)\n", + "native-image 21-beta 2023-09-19\n" + + "OpenJDK Runtime Environment Mandrel-23.0.0.1-devde078ae3bea (build 21-beta+35-ea)\n" + + "OpenJDK 64-Bit Server VM Mandrel-23.0.0.1-devde078ae3bea (build 21-beta+35-ea, mixed mode)"); } /** diff --git a/test-framework/junit5/src/main/java/io/quarkus/test/junit/DisableIfBuiltWithGraalVMNewerThanCondition.java b/test-framework/junit5/src/main/java/io/quarkus/test/junit/DisableIfBuiltWithGraalVMNewerThanCondition.java index 1e22d4dfa87947..57a48a22a72093 100644 --- a/test-framework/junit5/src/main/java/io/quarkus/test/junit/DisableIfBuiltWithGraalVMNewerThanCondition.java +++ b/test-framework/junit5/src/main/java/io/quarkus/test/junit/DisableIfBuiltWithGraalVMNewerThanCondition.java @@ -13,6 +13,8 @@ import org.junit.jupiter.api.extension.ExecutionCondition; import org.junit.jupiter.api.extension.ExtensionContext; +import io.quarkus.deployment.pkg.steps.GraalVM; + public class DisableIfBuiltWithGraalVMNewerThanCondition implements ExecutionCondition { private static final String QUARKUS_INTEGRATION_TEST_NAME = QuarkusIntegrationTest.class.getName(); @@ -33,9 +35,9 @@ public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext con GraalVMVersion annotationValue = optional.get().value(); Properties quarkusArtifactProperties = readQuarkusArtifactProperties(context); try { - org.graalvm.home.Version version = org.graalvm.home.Version - .parse(quarkusArtifactProperties.getProperty("metadata.graalvm.version.version")); - int comparison = annotationValue.compareTo(version); + GraalVM.Version version = GraalVM.Version + .of(quarkusArtifactProperties.getProperty("metadata.graalvm.version.version").lines()); + int comparison = annotationValue.getVersion().compareTo(version); if (comparison < 0) { return ConditionEvaluationResult.disabled("Native binary was built with GraalVM{version=" + version.toString() + "} but the test is disabled for GraalVM versions newer than " + annotationValue); diff --git a/test-framework/junit5/src/main/java/io/quarkus/test/junit/DisableIfBuiltWithGraalVMOlderThanCondition.java b/test-framework/junit5/src/main/java/io/quarkus/test/junit/DisableIfBuiltWithGraalVMOlderThanCondition.java index 805d8222f66dba..d7cf3db2398442 100644 --- a/test-framework/junit5/src/main/java/io/quarkus/test/junit/DisableIfBuiltWithGraalVMOlderThanCondition.java +++ b/test-framework/junit5/src/main/java/io/quarkus/test/junit/DisableIfBuiltWithGraalVMOlderThanCondition.java @@ -13,6 +13,8 @@ import org.junit.jupiter.api.extension.ExecutionCondition; import org.junit.jupiter.api.extension.ExtensionContext; +import io.quarkus.deployment.pkg.steps.GraalVM; + public class DisableIfBuiltWithGraalVMOlderThanCondition implements ExecutionCondition { private static final String QUARKUS_INTEGRATION_TEST_NAME = QuarkusIntegrationTest.class.getName(); @@ -33,9 +35,9 @@ public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext con GraalVMVersion annotationValue = optional.get().value(); Properties quarkusArtifactProperties = readQuarkusArtifactProperties(context); try { - org.graalvm.home.Version version = org.graalvm.home.Version - .parse(quarkusArtifactProperties.getProperty("metadata.graalvm.version.version")); - int comparison = annotationValue.compareTo(version); + GraalVM.Version version = GraalVM.Version + .of(quarkusArtifactProperties.getProperty("metadata.graalvm.version.version").lines()); + int comparison = annotationValue.getVersion().compareTo(version); if (comparison > 0) { return ConditionEvaluationResult.disabled("Native binary was built with GraalVM{version=" + version.toString() + "} but the test is disabled for GraalVM versions older than " + annotationValue); diff --git a/test-framework/junit5/src/main/java/io/quarkus/test/junit/GraalVMVersion.java b/test-framework/junit5/src/main/java/io/quarkus/test/junit/GraalVMVersion.java index 8ef1e0b52273f1..c157cfbdb0ff2d 100644 --- a/test-framework/junit5/src/main/java/io/quarkus/test/junit/GraalVMVersion.java +++ b/test-framework/junit5/src/main/java/io/quarkus/test/junit/GraalVMVersion.java @@ -1,34 +1,24 @@ package io.quarkus.test.junit; +import io.quarkus.deployment.pkg.steps.GraalVM; + public enum GraalVMVersion { - GRAALVM_21_0(org.graalvm.home.Version.create(21, 0)), - GRAALVM_22_0(org.graalvm.home.Version.create(22, 0)), - GRAALVM_22_1(org.graalvm.home.Version.create(22, 1)); + GRAALVM_23_1_0(GraalVM.Version.VERSION_23_1_0); - private final org.graalvm.home.Version version; + private final GraalVM.Version version; - GraalVMVersion(org.graalvm.home.Version version) { + GraalVMVersion(GraalVM.Version version) { this.version = version; } - public org.graalvm.home.Version getVersion() { + public GraalVM.Version getVersion() { return version; } - /** - * Compares this version with another GraalVM version - * - * @return {@code -1} if this version is older than the other version, - * {@code +1} if it's newer and {@code 0} if they represent the same version - */ - public int compareTo(org.graalvm.home.Version version) { - return this.version.compareTo(version); - } - @Override public String toString() { return "GraalVMVersion{" + - "version=" + version.toString() + + "version=" + version.getVersionAsString() + '}'; } }