Skip to content

Commit

Permalink
Merge pull request #36267 from zakkak/2023-10-03-improve-version-parsing
Browse files Browse the repository at this point in the history
Work around missing GraalVM internal version starting with JDK 22
  • Loading branch information
gsmet authored Oct 5, 2023
2 parents b9b923c + fe25fa5 commit edb0616
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -62,10 +63,16 @@ static Version parse(List<String> lines) {
String vendorVersion = secondMatcher.group(VENDOR_VERSION_GROUP);

String buildInfo = secondMatcher.group(BUILD_INFO_GROUP);
String graalVersion = graalVersion(buildInfo);
String graalVersion = graalVersion(buildInfo, v.feature());
if (vendorVersion.contains("-dev")) {
graalVersion = graalVersion + "-dev";
}
String mandrelVersion = mandrelVersion(vendorVersion);
Distribution dist = isMandrel(vendorVersion) ? Distribution.MANDREL : Distribution.ORACLE;
Distribution dist = isMandrel(vendorVersion) ? Distribution.MANDREL : Distribution.GRAALVM;
String versNum = (dist == Distribution.MANDREL ? mandrelVersion : graalVersion);
if (versNum == null) {
return UNKNOWN_VERSION;
}
return new Version(lines.stream().collect(Collectors.joining("\n")),
versNum, v.feature(), v.update(), dist);
} else {
Expand Down Expand Up @@ -100,7 +107,7 @@ private static String matchVersion(String version) {
return null;
}

private static String graalVersion(String buildInfo) {
private static String graalVersion(String buildInfo, int jdkFeature) {
if (buildInfo == null) {
return null;
}
Expand All @@ -109,10 +116,23 @@ private static String graalVersion(String buildInfo) {
return null;
}
String version = buildInfo.substring(idx + JVMCI_BUILD_PREFIX.length());
return matchVersion(version);
Matcher versMatcher = VERSION_PATTERN.matcher(version);
if (versMatcher.find()) {
return matchVersion(version);
} else {
return GRAAL_MAPPING.get(jdkFeature);
}
}
}

// Temporarily work around https://github.com/quarkusio/quarkus/issues/36246,
// till we have a consensus on how to move forward in
// https://github.com/quarkusio/quarkus/issues/34161
private static final Map<Integer, String> GRAAL_MAPPING = Map.of(22, "24.0",
23, "24.1",
24, "25.0",
25, "25.1");

public static final class Version implements Comparable<Version> {

/**
Expand All @@ -127,12 +147,12 @@ public static final class Version implements Comparable<Version> {
"(GraalVM|native-image)( Version)? " + VersionParseHelper.VERS_FORMAT + "(?<distro>.*?)?" +
"(\\(Java Version (?<jfeature>[0-9]+)(\\.(?<jinterim>[0-9]*)\\.(?<jupdate>[0-9]*))?.*)?$");

static final Version VERSION_21_3 = new Version("GraalVM 21.3", "21.3", Distribution.ORACLE);
static final Version VERSION_21_3_0 = new Version("GraalVM 21.3.0", "21.3.0", Distribution.ORACLE);
public static final Version VERSION_22_3_0 = new Version("GraalVM 22.3.0", "22.3.0", Distribution.ORACLE);
public static final Version VERSION_22_2_0 = new Version("GraalVM 22.2.0", "22.2.0", Distribution.ORACLE);
public static final Version VERSION_23_0_0 = new Version("GraalVM 23.0.0", "23.0.0", Distribution.ORACLE);
public static final Version VERSION_23_1_0 = new Version("GraalVM 23.1.0", "23.1.0", Distribution.ORACLE);
static final Version VERSION_21_3 = new Version("GraalVM 21.3", "21.3", Distribution.GRAALVM);
static final Version VERSION_21_3_0 = new Version("GraalVM 21.3.0", "21.3.0", Distribution.GRAALVM);
public static final Version VERSION_22_3_0 = new Version("GraalVM 22.3.0", "22.3.0", Distribution.GRAALVM);
public static final Version VERSION_22_2_0 = new Version("GraalVM 22.2.0", "22.2.0", Distribution.GRAALVM);
public static final Version VERSION_23_0_0 = new Version("GraalVM 23.0.0", "23.0.0", Distribution.GRAALVM);
public static final Version VERSION_23_1_0 = new Version("GraalVM 23.1.0", "23.1.0", Distribution.GRAALVM);

public static final Version MINIMUM = VERSION_22_2_0;
public static final Version CURRENT = VERSION_23_0_0;
Expand Down Expand Up @@ -226,7 +246,10 @@ public static Version of(Stream<String> output) {

if (lines.size() == 3) {
// Attempt to parse the new 3-line version scheme first.
return VersionParseHelper.parse(lines);
Version parsedVersion = VersionParseHelper.parse(lines);
if (parsedVersion != VersionParseHelper.UNKNOWN_VERSION) {
return parsedVersion;
}
} else if (lines.size() == 1) {
// Old, single line version parsing logic
final String line = lines.get(0);
Expand All @@ -249,7 +272,7 @@ public static Version of(Stream<String> output) {
version,
jFeature,
jUpdate,
isMandrel(distro) ? Distribution.MANDREL : Distribution.ORACLE);
isMandrel(distro) ? Distribution.MANDREL : Distribution.GRAALVM);
}
}

Expand Down Expand Up @@ -290,7 +313,7 @@ public boolean isJava17() {
}

enum Distribution {
ORACLE,
GRAALVM,
MANDREL;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -459,9 +459,10 @@ private RuntimeException imageGenerationFailed(int exitValue, boolean isContaine
}

private void checkGraalVMVersion(GraalVM.Version version) {
log.info("Running Quarkus native-image plugin on " + version.getFullVersion());
log.info("Running Quarkus native-image plugin on " + version.distribution.name() + " " + version.getVersionAsString()
+ " JDK " + version.javaFeatureVersion + "." + version.javaUpdateVersion);
if (version.isObsolete()) {
throw new IllegalStateException("Out of date version of GraalVM detected: " + version.getFullVersion() + "."
throw new IllegalStateException("Out of date version of GraalVM detected: " + version.getVersionAsString() + "."
+ " Quarkus currently supports " + GraalVM.Version.CURRENT.getVersionAsString()
+ ". Please upgrade GraalVM to this version.");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.quarkus.deployment.pkg.steps;

import static io.quarkus.deployment.pkg.steps.GraalVM.Distribution.GRAALVM;
import static io.quarkus.deployment.pkg.steps.GraalVM.Distribution.MANDREL;
import static io.quarkus.deployment.pkg.steps.GraalVM.Distribution.ORACLE;
import static org.assertj.core.api.Assertions.assertThat;

import java.util.stream.Stream;
Expand All @@ -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(new Version("GraalVM 23.0.0", "23.0.0", ORACLE), MANDREL,
assertVersion(new Version("GraalVM 23.0.0", "23.0.0", GRAALVM), 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(new Version("GraalVM 23.0.0", "23.0.0", ORACLE), MANDREL,
assertVersion(new Version("GraalVM 23.0.0", "23.0.0", GRAALVM), 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(new Version("GraalVM 23.0.0", "23.0.0", ORACLE), MANDREL,
assertVersion(new Version("GraalVM 23.0.0", "23.0.0", GRAALVM), 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(new Version("GraalVM 23.0.0", "23.0.0", ORACLE), MANDREL,
assertVersion(new Version("GraalVM 23.0.0", "23.0.0", GRAALVM), 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"
Expand All @@ -57,31 +57,31 @@ 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(new Version("GraalVM 23.0", "23.0", ORACLE), ORACLE,
assertVersion(new Version("GraalVM 23.0", "23.0", GRAALVM), GRAALVM,
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(new Version("GraalVM 20.1", "20.1", ORACLE), ORACLE,
assertVersion(new Version("GraalVM 20.1", "20.1", GRAALVM), GRAALVM,
Version.of(Stream.of("GraalVM Version 20.1.0 (Java Version 11.0.7)")));
assertVersion(new Version("GraalVM 20.1.0.1", "20.1.0.1", ORACLE), MANDREL, Version
assertVersion(new Version("GraalVM 20.1.0.1", "20.1.0.1", GRAALVM), MANDREL, Version
.of(Stream.of("GraalVM Version 20.1.0.1.Alpha2 56d4ee1b28 (Mandrel Distribution) (Java Version 11.0.8)")));
assertVersion(new Version("GraalVM 20.1.0.1", "20.1.0.1", ORACLE), MANDREL, Version
assertVersion(new Version("GraalVM 20.1.0.1", "20.1.0.1", GRAALVM), MANDREL, Version
.of(Stream.of("GraalVM Version 20.1.0.1-Final 56d4ee1b28 (Mandrel Distribution) (Java Version 11.0.8)")));
assertVersion(new Version("GraalVM 21.0", "21.0", ORACLE), MANDREL, Version
assertVersion(new Version("GraalVM 21.0", "21.0", GRAALVM), MANDREL, Version
.of(Stream.of("GraalVM Version 21.0.0.0-0b3 (Mandrel Distribution) (Java Version 11.0.8)")));
assertVersion(new Version("GraalVM 20.3.1.2", "20.3.1.2", ORACLE), MANDREL, Version
assertVersion(new Version("GraalVM 20.3.1.2", "20.3.1.2", GRAALVM), MANDREL, Version
.of(Stream.of("GraalVM Version 20.3.1.2-dev (Mandrel Distribution) (Java Version 11.0.8)")));
assertVersion(new Version("GraalVM 21.1", "21.1", ORACLE), MANDREL, Version
assertVersion(new Version("GraalVM 21.1", "21.1", GRAALVM), MANDREL, Version
.of(Stream.of("native-image 21.1.0.0-Final (Mandrel Distribution) (Java Version 11.0.11+9)")));
assertVersion(new Version("GraalVM 21.1", "21.1", ORACLE), MANDREL, Version
assertVersion(new Version("GraalVM 21.1", "21.1", GRAALVM), MANDREL, Version
.of(Stream.of("GraalVM 21.1.0.0-Final (Mandrel Distribution) (Java Version 11.0.11+9)")));
assertVersion(new Version("GraalVM 21.1", "21.1", ORACLE), ORACLE, Version
assertVersion(new Version("GraalVM 21.1", "21.1", GRAALVM), GRAALVM, Version
.of(Stream.of("GraalVM 21.1.0 Java 11 CE (Java Version 11.0.11+5-jvmci-21.1-b02)")));
assertVersion(new Version("GraalVM 21.1", "21.1", ORACLE), ORACLE, Version
assertVersion(new Version("GraalVM 21.1", "21.1", GRAALVM), GRAALVM, Version
.of(Stream.of("native-image 21.1.0.0 Java 11 CE (Java Version 11.0.11+5-jvmci-21.1-b02)")));
assertVersion(new Version("GraalVM 21.2", "21.2", ORACLE), MANDREL, Version
assertVersion(new Version("GraalVM 21.2", "21.2", GRAALVM), MANDREL, Version
.of(Stream.of("native-image 21.2.0.0-Final Mandrel Distribution (Java Version 11.0.12+7)")));
}

Expand All @@ -93,6 +93,39 @@ static void assertVersion(Version graalVmVersion, Distribution distro, Version v
}
}

@Test
public void testGraalVM21VersionParser() {
Version graalVM21Dev = Version.of(Stream.of(("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)").split("\\n")));
assertThat(graalVM21Dev.distribution.name()).isEqualTo("GRAALVM");
assertThat(graalVM21Dev.getVersionAsString()).isEqualTo("23.1");
assertThat(graalVM21Dev.javaFeatureVersion).isEqualTo(21);
assertThat(graalVM21Dev.javaUpdateVersion).isEqualTo(0);
}

@Test
public void testGraalVM21DevVersionParser() {
Version graalVM21Dev = Version.of(Stream.of(("native-image 21 2023-09-19\n" +
"GraalVM Runtime Environment GraalVM CE 21-dev+35.1 (build 21+35-jvmci-23.1-b14)\n" +
"Substrate VM GraalVM CE 21-dev+35.1 (build 21+35, serial gc)").split("\\n")));
assertThat(graalVM21Dev.distribution.name()).isEqualTo("GRAALVM");
assertThat(graalVM21Dev.getVersionAsString()).isEqualTo("23.1-dev");
assertThat(graalVM21Dev.javaFeatureVersion).isEqualTo(21);
assertThat(graalVM21Dev.javaUpdateVersion).isEqualTo(0);
}

@Test
public void testGraalVM22DevVersionParser() {
Version graalVM22Dev = Version.of(Stream.of(("native-image 22 2024-03-19\n"
+ "GraalVM Runtime Environment GraalVM CE 22-dev+16.1 (build 22+16-jvmci-b01)\n"
+ "Substrate VM GraalVM CE 22-dev+16.1 (build 22+16, serial gc)").split("\\n")));
assertThat(graalVM22Dev.distribution.name()).isEqualTo("GRAALVM");
assertThat(graalVM22Dev.getVersionAsString()).isEqualTo("24.0-dev");
assertThat(graalVM22Dev.javaFeatureVersion).isEqualTo(22);
assertThat(graalVM22Dev.javaUpdateVersion).isEqualTo(0);
}

@Test
public void testGraalVMVersionsOlderThan() {
assertOlderThan("GraalVM Version 19.3.6 CE", "GraalVM Version 20.2.0 (Java Version 11.0.9)");
Expand Down

0 comments on commit edb0616

Please sign in to comment.