{"record":{"id":"758202c5719659f5","repo":"apache/shenyu","slug":"get-join-name-is-null","errorCode":null,"errorMessage":"get join name is null","messagePattern":"get join name is null","errorType":"exception","errorClass":"NullPointerException","httpStatus":null,"severity":"error","filePath":"shenyu-spi/src/main/java/org/apache/shenyu/spi/ExtensionLoader.java","lineNumber":142,"sourceCode":"     * @return the default join.\n     */\n    public T getDefaultJoin() {\n        getExtensionClassesEntity();\n        if (StringUtils.isBlank(cachedDefaultName)) {\n            return null;\n        }\n        return getJoin(cachedDefaultName);\n    }\n    \n    /**\n     * Gets join.\n     *\n     * @param name the name\n     * @return the join.\n     */\n    public T getJoin(final String name) {\n        if (StringUtils.isBlank(name)) {\n            throw new NullPointerException(\"get join name is null\");\n        }\n        ClassEntity classEntity = getExtensionClassesEntity().get(name);\n        if (Objects.isNull(classEntity)) {\n            throw new IllegalArgumentException(name + \" name is error\");\n        }\n        if (!classEntity.isSingleton()) {\n            return (T) createExtension(classEntity);\n        }\n        Holder<Object> objectHolder = cachedInstances.get(name);\n        if (Objects.isNull(objectHolder)) {\n            cachedInstances.putIfAbsent(name, new Holder<>());\n            objectHolder = cachedInstances.get(name);\n        }\n        Object value = objectHolder.getValue();\n        if (Objects.isNull(value)) {\n            synchronized (objectHolder) {\n                value = objectHolder.getValue();\n                if (Objects.isNull(value)) {","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/apache/shenyu/blob/567142e07261b3e615ae8850b30f4421f455cc5d/shenyu-spi/src/main/java/org/apache/shenyu/spi/ExtensionLoader.java#L124-L160","documentation":"ExtensionLoader.getJoin(name) throws NullPointerException when the requested join/extension name is blank (null or whitespace). Names map to implementations registered in META-INF/shenyu/ files, so a name is mandatory to look one up.","triggerScenarios":"Calling loader.getJoin(null) or loader.getJoin(\"\") or getJoin(\"  \"), typically when the name comes from unvalidated configuration.","commonSituations":"Config property for algorithm/load-balance name never set; a null returned by an upstream lookup passed straight into getJoin; typo in variable use.","solutions":["Ensure the name passed to getJoin is a non-blank string","Validate/resolve configuration before calling getJoin","Use getDefaultJoin() when no specific name is needed"],"exampleFix":"// before\nLoadBalance lb = loader.getJoin(config.getAlgorithm());\n// after\nLoadBalance lb = StringUtils.isNotBlank(config.getAlgorithm())\n        ? loader.getJoin(config.getAlgorithm()) : loader.getDefaultJoin();","handlingStrategy":"validation","validationCode":"if (StringUtils.isBlank(name)) { name = defaultName; } // resolve before lookup\nLoadBalance lb = loader.getJoin(name);","typeGuard":"static boolean validName(String n) { return n != null && !n.trim().isEmpty(); }","tryCatchPattern":"try { return loader.getJoin(name); } catch (NullPointerException e) { log.warn(\"Blank extension name, using default\"); return loader.getDefaultJoin(); }","preventionTips":["Validate configuration strings before passing them to getJoin","Prefer getDefaultJoin() when the name is optional","Fail fast at config-load time on blank extension names"],"tags":["spi","null","argument-validation"],"backgroundTag":"null-argument","analyzedSha":"567142e07261b3e615ae8850b30f4421f455cc5d","analyzedAt":"2026-09-12T10:08:21.293Z","contentChangedAt":"2026-09-12T10:08:21.293Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}