11package io .quarkus .runtime .graal ;
22
33import java .util .Arrays ;
4+ import java .util .Collections ;
5+ import java .util .HashMap ;
46import java .util .Map ;
7+ import java .util .Map .Entry ;
58import java .util .regex .Matcher ;
69import java .util .regex .Pattern ;
710import java .util .stream .Collectors ;
@@ -40,16 +43,23 @@ static final class VersionParseHelper {
4043
4144 private static final String VERSION_GROUP = "VNUM" ;
4245
43- private static final Version UNKNOWN_VERSION = null ;
44-
4546 static Version parse (String value ) {
4647 Matcher versionMatcher = VENDOR_VERS_PATTERN .matcher (value );
4748 if (versionMatcher .find ()) {
4849 String vendor = versionMatcher .group (VENDOR_PREFIX_GROUP );
4950 if (GRAALVM_CE_VERS_PREFIX .equals (vendor ) || ORACLE_GRAALVM_VERS_PREFIX .equals (vendor )) {
5051 String version = versionMatcher .group (VERSION_GROUP );
51- String jdkFeature = version .split ("\\ ." , 2 )[0 ];
52- return new Version (value , Version .GRAAL_MAPPING .get (jdkFeature ), Distribution .GRAALVM );
52+ String tokens [] = version .split ("\\ ." , 3 );
53+ String jdkFeature = tokens [0 ];
54+ String jdkVers = jdkFeature ;
55+ if (tokens .length == 3 ) {
56+ String interim = tokens [1 ];
57+ String update = tokens [2 ].split ("\\ +" )[0 ];
58+ jdkVers = String .format ("%s.%s.%s" , jdkFeature , interim , update );
59+ }
60+ // For JDK 26+ there is no more version mapping use the JDK version
61+ String versionMapping = Version .GRAAL_MAPPING .getOrDefault (jdkFeature , version );
62+ return new Version (value , versionMapping , jdkVers , Distribution .GRAALVM );
5363 } else if (LIBERICA_NIK_VERS_PREFIX .equals (vendor )) {
5464 return new Version (value , versionMatcher .group (VERSION_GROUP ), Distribution .LIBERICA );
5565 } else if (MANDREL_VERS_PREFIX .equals (vendor )) {
@@ -78,8 +88,18 @@ public static class Version implements Comparable<Version> {
7888 "21" , "23.1" ,
7989 "22" , "24.0" ,
8090 "23" , "24.1" ,
81- "24" , "24.2" ,
82- "25" , "25.0" );
91+ "24" , "24.2" );
92+ // Mapping of community major.minor pair to the JDK major version based on
93+ // GRAAL_MAPPING
94+ private static final Map <String , String > MANDREL_JDK_REV_MAP ;
95+
96+ static {
97+ Map <String , String > reverseMap = new HashMap <>(GRAAL_MAPPING .size ());
98+ for (Entry <String , String > entry : GRAAL_MAPPING .entrySet ()) {
99+ reverseMap .put (entry .getValue (), entry .getKey ());
100+ }
101+ MANDREL_JDK_REV_MAP = Collections .unmodifiableMap (reverseMap );
102+ }
83103
84104 /**
85105 * The minimum version of GraalVM supported by Quarkus.
@@ -97,14 +117,18 @@ public static class Version implements Comparable<Version> {
97117 */
98118 public static final Version MINIMUM_SUPPORTED = CURRENT ;
99119
120+ private static final String DEFAULT_JDK_VERSION = "21" ;
100121 protected final String fullVersion ;
101122 public final Runtime .Version javaVersion ;
102123 protected final Distribution distribution ;
103124 private int [] versions ;
104125 private String suffix ;
105126
106127 Version (String fullVersion , String version , Distribution distro ) {
107- this (fullVersion , version , "21" , distro );
128+ this (fullVersion , version ,
129+ distro == Distribution .MANDREL || distro == Distribution .LIBERICA ? communityJDKvers (version )
130+ : DEFAULT_JDK_VERSION ,
131+ distro );
108132 }
109133
110134 Version (String fullVersion , String version , String javaVersion , Distribution distro ) {
@@ -127,6 +151,33 @@ private void breakdownVersion(String version) {
127151 this .versions = Arrays .stream (version .split ("\\ ." )).mapToInt (Integer ::parseInt ).toArray ();
128152 }
129153
154+ /*
155+ * Reconstruct the JDK version from the given GraalVM community version (Mandrel or Liberica)
156+ */
157+ private static String communityJDKvers (String communityVersion ) {
158+ try {
159+ String [] parts = communityVersion .split ("\\ ." , 4 );
160+ int major = Integer .parseInt (parts [0 ]);
161+ int minor = Integer .parseInt (parts [1 ]);
162+ if ((major == 23 && minor > 0 ) ||
163+ major > 23 ) {
164+ String mandrelMajorMinor = String .format ("%s.%s" , parts [0 ], parts [1 ]);
165+ // If we don't find a reverse mapping we use a JDK version >= 25, thus
166+ // the feature version is the first part of the quadruple.
167+ String feature = MANDREL_JDK_REV_MAP .getOrDefault (mandrelMajorMinor , parts [0 ]);
168+ // Heuristic: The update version of Mandrel and the JDK match.
169+ // Interim is usually 0 for the JDK version.
170+ return String .format ("%s.%s.%s" , feature , "0" , parts [2 ]);
171+ }
172+ } catch (Throwable e ) {
173+ // fall-through do default
174+ Log .warnf ("Failed to parse JDK version from GraalVM version: %s. Defaulting to currently supported version %s " ,
175+ communityVersion ,
176+ DEFAULT_JDK_VERSION );
177+ }
178+ return DEFAULT_JDK_VERSION ;
179+ }
180+
130181 @ Override
131182 public int compareTo (Version o ) {
132183 return compareTo (o .versions );
0 commit comments