{"record":{"id":"36748f0d1ab15a8b","repo":"apache/pulsar","slug":"function-class-s-must-be-in-class-path","errorCode":null,"errorMessage":"Function class %s must be in class path","messagePattern":"Function class (.+?) must be in class path","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionConfigUtils.java","lineNumber":655,"sourceCode":"                    throw new IllegalArgumentException(\"Function class name is not provided.\");\n                }\n                functionClassName = functionDefinition.getFunctionClass();\n                if (functionClassName == null) {\n                    throw new IllegalArgumentException(\"Function class name is not provided.\");\n                }\n            }\n            functionClass = validatableFunctionPackage.resolveType(functionClassName);\n\n            if (!functionClass.asErasure().isAssignableTo(org.apache.pulsar.functions.api.Function.class)\n                    && !functionClass.asErasure().isAssignableTo(java.util.function.Function.class)\n                    && !functionClass.asErasure()\n                    .isAssignableTo(org.apache.pulsar.functions.api.WindowFunction.class)) {\n                throw new IllegalArgumentException(\n                        String.format(\"Function class %s does not implement the correct interface\",\n                                functionClassName));\n            }\n        } catch (TypePool.Resolution.NoSuchTypeException e) {\n            throw new IllegalArgumentException(\n                    String.format(\"Function class %s must be in class path\", functionClassName), e);\n        }\n\n        TypeDefinition[] typeArgs = FunctionCommon.getFunctionTypes(functionConfig, functionClass);\n        // inputs use default schema, so there is no check needed there\n\n        // Check if the Input serialization/deserialization class exists in jar or already loaded and that it\n        // implements SerDe class\n        if (functionConfig.getCustomSerdeInputs() != null) {\n            functionConfig.getCustomSerdeInputs().forEach((topicName, inputSerializer) -> {\n                ValidatorUtils.validateSerde(inputSerializer, typeArgs[0], validatableFunctionPackage.getTypePool(),\n                        true);\n            });\n        }\n\n        // Check if the Input serialization/deserialization class exists in jar or already loaded and that it\n        // implements SerDe class\n        if (functionConfig.getCustomSchemaInputs() != null) {","sourceCodeStart":637,"sourceCodeEnd":673,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionConfigUtils.java#L637-L673","documentation":"While resolving the configured function class via the NAR package TypePool, the type could not be found, so doJavaChecks throws IllegalArgumentException with the cause NoSuchTypeException. The class name resolved syntactically but the bytecode is not present in the function package.","triggerScenarios":"className references a class that is not contained in the submitted JAR/NAR (resolution by TypePool fails), including classes whose dependencies were not bundled.","commonSituations":"Shading/proguard stripped or renamed the class; fat JAR missing the function class; class name typo that still resolves as a valid binary name; dependency-only JAR submitted instead of the function JAR.","solutions":["Ensure the class named in className exists in the submitted archive (check jar tf / unzip -l)","Correct any typo in the fully qualified class name","Rebuild the fat/NAR package so the function class and its dependencies are bundled"],"exampleFix":"// before\nconfig.setClassName(\"org.example.MyFuntion\"); // typo, class not in jar\n// after\nconfig.setClassName(\"org.example.MyFunction\"); // present in the submitted jar","handlingStrategy":"validation","validationCode":"try (JarFile jar = new JarFile(archivePath)) { if (jar.getJarEntry(config.getClassName().replace('.', '/') + \".class\") == null) { throw new IllegalArgumentException(\"Class \" + config.getClassName() + \" not present in archive\"); } }","typeGuard":"boolean classInArchive(String archive, String fqcn) throws IOException { try (JarFile jf = new JarFile(archive)) { return jf.getJarEntry(fqcn.replace('.', '/') + \".class\") != null; } }","tryCatchPattern":"try { ... } catch (IllegalArgumentException e) { Throwable cause = e.getCause(); if (cause instanceof TypePool.Resolution.NoSuchTypeException) { log.error(\"Bundle the missing class into the function archive\"); } }","preventionTips":["Run 'jar tf' to confirm the class exists before submitting","Ensure shading config keeps the function class un-renamed","Submit the actual function fat JAR/NAR, not a dependency-only JAR"],"tags":["pulsar","functions","java","classpath"],"backgroundTag":"class-not-found-in-function-package","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}