apache/pulsar · error · ClassNotFoundException

ClassNotFoundException: className

Error message

ClassNotFoundException: className

What it means

Reflections.loadClass supports JVM field-type descriptors: primitive letters (B,C,D,F,I,J,S,Z,V), 'L<ClassName>;' for objects, and plain names. If className is a single unrecognized character that isn't a known primitive descriptor code, it throws ClassNotFoundException. This happens while parsing descriptor strings, not ordinary dotted class names.

Source

Thrown at pulsar-common/src/main/java/org/apache/pulsar/common/util/Reflections.java:304

                return Byte.TYPE;
            } else if (type == 'C') {
                return Character.TYPE;
            } else if (type == 'D') {
                return Double.TYPE;
            } else if (type == 'F') {
                return Float.TYPE;
            } else if (type == 'I') {
                return Integer.TYPE;
            } else if (type == 'J') {
                return Long.TYPE;
            } else if (type == 'S') {
                return Short.TYPE;
            } else if (type == 'Z') {
                return Boolean.TYPE;
            } else if (type == 'V') {
                return Void.TYPE;
            } else {
                throw new ClassNotFoundException(className);
            }
        } else if (isPrimitive(className)) {
            return PRIMITIVE_NAME_TYPE_MAP.get(className);
        } else if (className.charAt(0) == 'L' && className.charAt(className.length() - 1) == ';') {
            return classLoader.loadClass(className.substring(1, className.length() - 1));
        } else {
            try {
                return classLoader.loadClass(className);
            } catch (ClassNotFoundException | NoClassDefFoundError var4) {
                if (className.charAt(0) != '[') {
                    throw var4;
                } else {
                    // CHECKSTYLE.OFF: EmptyStatement
                    int arrayDimension;
                    for (arrayDimension = 0; className.charAt(arrayDimension) == '['; ++arrayDimension) {
                    }
                    // CHECKSTYLE.ON: EmptyStatement

View on GitHub (pinned to 820761864e)

Solutions

  1. Pass the full dotted class name (e.g. 'java.lang.String') or a correct descriptor: 'Ljava.lang.String;' for objects.
  2. Use a supported primitive code: B C D F I J S Z, or V for void.
  3. Pre-strip array brackets ('[') or handle them before calling loadClass.
  4. Log/inspect the className value at the call site — a single unexpected character usually means a malformed descriptor upstream.

Example fix

// before
loadClass(cl, "K");
// after
loadClass(cl, "I"); // or loadClass(cl, "com.example.MyClass");
Defensive patterns

Strategy: validation

Validate before calling

static final Set<Character> PRIMITIVES = Set.of('B','C','D','F','I','J','S','Z','V');
static boolean isSupportedTypeRef(String className) {
    if (className == null || className.isEmpty()) return false;
    if (className.length() == 1) return PRIMITIVES.contains(className.charAt(0));
    if (className.startsWith("L") && className.endsWith(";")) return true;
    return className.indexOf('.') > 0; // ordinary dotted name
}

Type guard

static boolean isPrimitiveDescriptor(String s) {
    return s != null && s.length() == 1 && "BCDFIJSZV".indexOf(s.charAt(0)) >= 0;
}

Try / catch

try { return Reflections.loadClass(classLoader, className); }
catch (ClassNotFoundException e) {
    if (className.length() == 1)
        throw new IllegalArgumentException("Unrecognized type descriptor '" + className
            + "'; use B C D F I J S Z V, 'L...;' or a dotted class name", e);
    throw e;
}

Prevention

When it happens

Trigger: Calling Reflections.loadClass(classLoader, className) with a one-character string that is not a valid primitive descriptor (e.g. 'X', 'A'), or a malformed descriptor string where the first char is taken as a type code.

Common situations: Parsing a JNI/method descriptor and encountering a type char that isn't supported; typo where only a single letter was passed instead of a full class name; unsupported descriptor like array type '[' prefix or generics leaking into the descriptor.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/cd9ebc89473e4193. Report an issue: GitHub.