oracle/graal · error · IllegalArgumentException
Class name "${className}" does not match pattern ${QUALIFIED
Error message
Class name "${className}" does not match pattern ${QUALIFIED_CLASS_NAME_RE} What it means
AbstractProcessor.getSimpleName(String) parses a fully qualified class name using the regex (?:[a-z]\\w*\\.)+([A-Z].*) — package components must start with a lowercase letter and the simple name must start with an uppercase letter. If the string does not match (no package part, uppercase-starting package segment, lowercase simple name, array/primitive names), it throws IllegalArgumentException at runtime inside the annotation processor. Callers hit this as a processing-time crash, often with a message naming the offending string.
Source
Thrown at compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/processor/AbstractProcessor.java:212
/**
* Regular expression for a qualified class name that assumes package names start with lowercase
* and non-package components start with uppercase.
*/
private static final Pattern QUALIFIED_CLASS_NAME_RE = Pattern.compile("(?:[a-z]\\w*\\.)+([A-Z].*)");
/**
* Gets the non-package component of a qualified class name.
*
* @throws IllegalArgumentException if {@code className} does not match
* {@link #QUALIFIED_CLASS_NAME_RE}
*/
public static String getSimpleName(String className) {
Matcher m = QUALIFIED_CLASS_NAME_RE.matcher(className);
if (m.matches()) {
return m.group(1);
}
throw new IllegalArgumentException("Class name \"" + className + "\" does not match pattern " + QUALIFIED_CLASS_NAME_RE);
}
/**
* Gets the package component of a qualified class name.
*
* @throws IllegalArgumentException if {@code className} does not match
* {@link #QUALIFIED_CLASS_NAME_RE}
*/
public static String getPackageName(String className) {
String simpleName = getSimpleName(className);
return className.substring(0, className.length() - simpleName.length() - 1);
}
/**
* Gets the annotation of type {@code annotationType} directly present on {@code element}.
*
* @return {@code null} if an annotation of type {@code annotationType} is not on
* {@code element}View on GitHub (pinned to a66e9ccd1d)
Solutions
- Pass a fully qualified name whose package segments start lowercase and whose simple name starts uppercase, e.g. 'com.mycompany.mynode.MyNode'.
- If you only have a simple name, prepend the correct package before calling getSimpleName/getPackageName.
- If the name is synthetic (inner classes, arrays), normalize it first (replace '$' handling, strip array descriptors) before parsing.
- If a package legitimately starts uppercase, rename it to follow Java conventions.
Example fix
// before
String simple = AbstractProcessor.getSimpleName("MyNode"); // throws
// after
String simple = AbstractProcessor.getSimpleName("org.graalvm.compiler.nodes.MyNode"); Defensive patterns
Strategy: try-catch
Validate before calling
private static final Pattern QUALIFIED = Pattern.compile("(?:[a-z]\\w*\\.)+([A-Z].*)");
static boolean isParsableQualifiedName(String className) {
return className != null && QUALIFIED.matcher(className).matches();
}
// use before calling AbstractProcessor.getSimpleName/getPackageName
if (!isParsableQualifiedName(name)) {
name = expectedPackage + "." + name; // or skip/reject
} Try / catch
try {
String simple = AbstractProcessor.getSimpleName(className);
} catch (IllegalArgumentException e) {
// log the offending name and skip this element; do not retry with the same string
} Prevention
- Always pass fully qualified names (package lowercase-first segments, class uppercase-first) to getSimpleName/getPackageName.
- Never feed Class.getSimpleName(), array descriptors, or '$'-containing inner-class names into these helpers without normalizing.
- Follow Java naming conventions for packages (lowercase) — the regex hard-codes them.
When it happens
Trigger: Calling getSimpleName (or getPackageName, which delegates to it) with a value like 'MyClass' (no package), 'com.Testnode.lower' or 'MyPkg.Foo' — i.e. anything violating '(?:[a-z]\\w*\\.)+([A-Z].*)'. Inside the processor suite this typically happens when a node/processor metadata lookup receives an unexpected or synthetic class name.
Common situations: Annotation processors fed simple names instead of qualified names (e.g. from Class.getSimpleName() or a missed package prefix); packages whose names start with uppercase (violating conventions); refactoring tooling that generates names like 'Outer$Inner' or array descriptors passed where a plain qualified name was expected.
Related errors
- Invalid trailing characters.
- Invalid character at index ${cur} in signature: ${signature}
- Type with name %s not found.
- Captured node "%s" has differing types
- Input list field must not be final
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/f25a2bc0cb7a1525.
Report an issue: GitHub.