oracle/graal · error · IllegalArgumentException
Unsupported java version: {} ({})
Error message
Unsupported java version: {} ({}) What it means
JavaVersion.forVersion(String) strips an optional '1.' prefix (1.8 -> 8) and takes everything up to the next dot, then Integer.parseInt. If that normalized substring is not an integer, NumberFormatException is wrapped in IllegalArgumentException showing both the original and normalized version.
Source
Thrown at espresso-shared/src/com.oracle.truffle.espresso.classfile/src/com/oracle/truffle/espresso/classfile/JavaVersion.java:110
return new JavaVersion(version);
}
public static JavaVersion forVersion(String version) {
int begin = 0;
int end = version.length();
if (version.startsWith("1.")) {
begin = 2;
}
int firstDot = version.indexOf('.', begin);
if (firstDot >= 0) {
end = firstDot;
}
String normalizedVersion = version.substring(begin, end);
try {
int intVersion = Integer.parseInt(normalizedVersion);
return forVersion(intVersion);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Unsupported java version: " + version + " (" + normalizedVersion + ")");
}
}
public Runtime.Version toRunTimeVersion() {
return Runtime.Version.parse(toString());
}
private static JavaVersion forVersion(Runtime.Version version) {
return forVersion(version.feature());
}
public static JavaVersion latestSupported() {
return forVersion(LATEST_SUPPORTED);
}
public boolean java8OrEarlier() {
return version <= 8;
}View on GitHub (pinned to a66e9ccd1d)
Solutions
- Normalize first: strip prefixes/suffixes and keep only the leading digit run (e.g. regex ^(1\.)?(\d+)) before calling forVersion
- For runtime use Runtime.Version.parse(...).feature() and the Runtime.Version overload instead of hand-parsing strings
- Reject empty/blank input early with a clear configuration error
Example fix
// before
JavaVersion v = JavaVersion.forVersion("17-ea"); // NumberFormatException on '17-ea'
// after
Matcher m = Pattern.compile("^(?:1\.)?(\d+)").matcher(version);
JavaVersion v = m.find() ? JavaVersion.forVersion(Integer.parseInt(m.group(1))) : JavaVersion.latestSupported(); Defensive patterns
Strategy: validation
Validate before calling
Matcher m = Pattern.compile("^(?:1\.)?(\d+)").matcher(version);
if (!m.find()) throw new IllegalArgumentException("Unparseable version: " + version);
JavaVersion.forVersion(Integer.parseInt(m.group(1))); Type guard
static boolean isParsableVersion(String s) { return s != null && Pattern.compile("^(?:1\.)?\d+").matcher(s).find(); } Try / catch
catch (IllegalArgumentException e) { show original and normalized strings, reject the config input } Prevention
- Prefer Runtime.Version.parse(...).feature() for JDK version strings
- Strip suffixes like 'u40', '-ea', '_282' before handing the string over
When it happens
Trigger: Passing strings like 'abc', '1.x', 'v17', '17-pre2', '8u40', or '' (empty) — any version string whose leading dot-free segment is not purely digits.
Common situations: Feeding System.getProperty('java.version') raw values from old JDKs ('1.8.0_282' works, but '8u40' or '17-ea' do not), user-supplied --release style flags, or build metadata accidentally concatenated to the version string.
Related errors
- unknown primitive or void type character:
- Unsupported java version:
- Invalid method signature: {}
- invalid descriptor: {}
- invalid type descriptor: {}
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/ba40912912bc309a.
Report an issue: GitHub.