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

  1. Pass a fully qualified name whose package segments start lowercase and whose simple name starts uppercase, e.g. 'com.mycompany.mynode.MyNode'.
  2. If you only have a simple name, prepend the correct package before calling getSimpleName/getPackageName.
  3. If the name is synthetic (inner classes, arrays), normalize it first (replace '$' handling, strip array descriptors) before parsing.
  4. 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

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


AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14). Data as JSON: /api/errors/f25a2bc0cb7a1525. Report an issue: GitHub.