{"record":{"id":"afbd2fb7d0b3d16f","repo":"apache/dubbo","slug":"class-not-found-desc","errorCode":null,"errorMessage":"Class not found: ${desc}","messagePattern":"Class not found: (.+?)","errorType":"exception","errorClass":"ClassNotFoundException","httpStatus":null,"severity":"error","filePath":"dubbo-common/src/main/java/org/apache/dubbo/common/utils/ReflectUtils.java","lineNumber":843,"sourceCode":"                return double.class;\n            case JVM_FLOAT:\n                return float.class;\n            case JVM_INT:\n                return int.class;\n            case JVM_LONG:\n                return long.class;\n            case JVM_SHORT:\n                return short.class;\n            case 'L':\n                // \"Ljava/lang/Object;\" ==> \"java.lang.Object\"\n                desc = desc.substring(1, desc.length() - 1).replace('/', '.');\n                break;\n            case '[':\n                // \"[[Ljava/lang/Object;\" ==> \"[[Ljava.lang.Object;\"\n                desc = desc.replace('/', '.');\n                break;\n            default:\n                throw new ClassNotFoundException(\"Class not found: \" + desc);\n        }\n\n        if (cl == null) {\n            cl = ClassUtils.getClassLoader();\n        }\n        return Class.forName(desc, true, cl);\n    }\n\n    /**\n     * get class array instance.\n     *\n     * @param desc desc.\n     * @return Class class array.\n     * @throws ClassNotFoundException\n     */\n    public static Class<?>[] desc2classArray(String desc) throws ClassNotFoundException {\n        Class<?>[] ret = desc2classArray(ClassUtils.getClassLoader(), desc);\n        return ret;","sourceCodeStart":825,"sourceCodeEnd":861,"githubUrl":"https://github.com/apache/dubbo/blob/3a3043227f5571d25eb2889de5bca22f2914843b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ReflectUtils.java#L825-L861","documentation":"Inside name2class(ClassLoader cl, String desc), after handling primitive type codes and the 'L' (object) and '[' (array) cases, a default branch throws ClassNotFoundException for any descriptor string that starts with an unrecognized character. This means the descriptor is neither a valid primitive code, an object reference (L...;), nor an array ([...]).","triggerScenarios":"Calling ReflectUtils.name2class with a JVM descriptor string that doesn't begin with a recognized type code. For example, passing a descriptor like 'Xjava/lang/String;' or a plain class name like 'java.lang.String' where the method expects internal JVM descriptor format. Note: name2class also handles plain names in its public entry point, but the internal descriptor path is strict.","commonSituations":"Internal Dubbo serialization code passing a malformed descriptor string, or a custom protocol extension that constructs descriptors incorrectly. The public name2class(String name) entry point handles plain names and delegates to this descriptor-parsing path for array/object forms; a programming error in constructing the descriptor format triggers this.","solutions":["Inspect the desc string in the exception message to see what was passed — it must start with a valid JVM type code.","If passing a plain class name, use the public name2class(String name) entry, not the internal descriptor parser.","For object types, ensure descriptors use 'L' prefix and ';' suffix (e.g. 'Ljava/lang/String;').","For arrays, ensure the '[' prefix is present (e.g. '[Ljava/lang/String;' or '[I')."],"exampleFix":"// before — invalid descriptor\nReflectUtils.name2class(cl, \"java/lang/String\"); // no 'L' prefix\n// after — valid JVM descriptor\nReflectUtils.name2class(cl, \"Ljava/lang/String;\");\n// or use plain name entry point\nReflectUtils.forName(\"java.lang.String\");","handlingStrategy":"validation","validationCode":"// Validate JVM descriptor format before calling name2class\nprivate static final Set<Character> VALID_PRIMITIVE_CODES =\n    Set.of('B', 'C', 'D', 'F', 'I', 'J', 'S', 'Z', 'V');\n\nvoid validateDescriptor(String desc) {\n    if (desc == null || desc.isEmpty()) {\n        throw new IllegalArgumentException(\"Empty descriptor\");\n    }\n    char c = desc.charAt(0);\n    if (c == 'L' || c == '[' || VALID_PRIMITIVE_CODES.contains(c)) return;\n    throw new IllegalArgumentException(\n        \"Invalid JVM descriptor starting with '\" + c + \"': \" + desc);\n}","typeGuard":null,"tryCatchPattern":"try {\n    return ReflectUtils.name2class(cl, desc);\n} catch (ClassNotFoundException e) {\n    if (e.getMessage().contains(\"Class not found:\")) {\n        logger.error(\"Malformed descriptor: {}\", desc);\n    }\n    throw e;\n}","preventionTips":["Use the public name2class(String name) entry point for plain class names, not the internal descriptor parser.","Derive descriptors from Class.getName() or reflection rather than constructing them manually.","Validate descriptor strings against the JVM spec format in tests."],"tags":["reflection","jvm-descriptor","classloading","internal"],"backgroundTag":null,"analyzedSha":"3a3043227f5571d25eb2889de5bca22f2914843b","analyzedAt":"2026-08-14T00:43:19.853Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}