{"record":{"id":"b280646e83723a85","repo":"pinpoint-apm/pinpoint","slug":"class-name-must-not-be-null","errorCode":null,"errorMessage":"class name must not be null","messagePattern":"class name must not be null","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"commons/src/main/java/com/navercorp/pinpoint/common/util/ClassUtils.java","lineNumber":70,"sourceCode":"        Objects.requireNonNull(fqcn, \"fqcn\");\r\n\r\n        final int lastPackageSeparatorIndex = fqcn.lastIndexOf(packageSeparator);\r\n        if (lastPackageSeparatorIndex == -1) {\r\n            return defaultValue;\r\n        }\r\n        return fqcn.substring(0, lastPackageSeparatorIndex);\r\n    }\r\n\r\n    public static String getPackageName(String fqcn) {\r\n        return getPackageName(fqcn, PACKAGE_SEPARATOR, \"\");\r\n    }\r\n\r\n    /**\r\n     * convert \".\" based name to \"/\" based internal name.\r\n     */\r\n    public static String toInternalName(final String className) {\r\n        if (className == null) {\r\n            throw new IllegalArgumentException(\"class name must not be null\");\r\n        }\r\n        return className.replace('.', '/');\r\n    }\r\n}","sourceCodeStart":52,"sourceCodeEnd":74,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/commons/src/main/java/com/navercorp/pinpoint/common/util/ClassUtils.java#L52-L74","documentation":"ClassUtils.toInternalName converts a Java binary class name to JVM internal form by replacing '.' with '/' (e.g. com.foo.Bar -> com/foo/Bar). A null class name cannot be converted, so the method throws IllegalArgumentException as a precondition check.","triggerScenarios":"Calling ClassUtils.toInternalName(null), typically when a class name was obtained from a lookup that returned null (Class.getName on a missing class, config field not set, or reflection metadata absent).","commonSituations":"Instrumentation/agent configuration where a target class name placeholder is unset, or code paths building bytecode names from nullable reflection results.","solutions":["Ensure the class name is resolved and non-null before conversion; fail earlier with a clear config error.","Guard the call site with a null check or Objects.requireNonNull with a descriptive message.","Trace where the null originates — usually a missing configuration entry or an unloaded/unknown class."],"exampleFix":"// before\nString internal = ClassUtils.toInternalName(config.getTargetClass());\n// after\nString target = config.getTargetClass();\nif (target == null) {\n    throw new IllegalStateException(\"targetClass is not configured\");\n}\nString internal = ClassUtils.toInternalName(target);","handlingStrategy":"type-guard","validationCode":"if (className == null || className.isEmpty()) {\n    throw new IllegalStateException(\"class name not configured\");\n}","typeGuard":"boolean hasClassName(String cn) { return cn != null && !cn.isEmpty(); }","tryCatchPattern":"try {\n    return ClassUtils.toInternalName(className);\n} catch (IllegalArgumentException e) {\n    throw new ConfigurationException(\"Target class name is null; check agent config\", e);\n}","preventionTips":["Resolve configuration into non-null values at startup with fail-fast checks","Avoid passing raw reflection lookups (possibly null) into name converters","Validate instrumentation target config before use"],"tags":["null-check","class-utils","jvm","argument-validation"],"backgroundTag":"null-argument","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}