{"record":{"id":"40440253c24015e2","repo":"apache/pulsar","slug":"field-name-with-value-o-does-not-impleme","errorCode":null,"errorMessage":"Field '${name}' with value '${o}' does not implement ${classImplements.getName()} ","messagePattern":"Field '(.+?)' with value '(.+?)' does not implement (.+?) ","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-config-validation/src/main/java/org/apache/pulsar/config/validation/ValidatorImpls.java","lineNumber":158,"sourceCode":"            this.classImplements = (Class<?>) params.get(ConfigValidationAnnotations.ValidatorParams.IMPLEMENTS_CLASS);\n        }\n\n        public ImplementsClassValidator(Class<?> classImplements) {\n            this.classImplements = classImplements;\n        }\n\n        @Override\n        public void validateField(String name, Object o) {\n            if (o == null) {\n                return;\n            }\n            SimpleTypeValidator.validateField(name, String.class, o);\n            String className = (String) o;\n            try {\n                ClassLoader clsLoader = Thread.currentThread().getContextClassLoader();\n                Class<?> objectClass = clsLoader.loadClass(className);\n                if (!this.classImplements.isAssignableFrom(objectClass)) {\n                    throw new IllegalArgumentException(\n                            String.format(\"Field '%s' with value '%s' does not implement %s \",\n                                    name, o, this.classImplements.getName()));\n                }\n            } catch (ClassNotFoundException e) {\n                throw new RuntimeException(e);\n            }\n        }\n    }\n\n    /**\n     * validates class implements one of these classes.\n     */\n    public static class ImplementsClassesValidator extends Validator {\n\n        Class<?>[] classesImplements;\n\n        public ImplementsClassesValidator(Map<String, Object> params) {\n            this.classesImplements = (Class<?>[]) params.get(","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-config-validation/src/main/java/org/apache/pulsar/config/validation/ValidatorImpls.java#L140-L176","documentation":"This IllegalArgumentException is thrown by a class-assignment validator during config validation. It first coerces the value to a String, loads the named class via the thread context classloader, and checks that the class is assignable to the interface/class the validator was constructed with. If the class loads but does not implement/extend the required type, validation of the field fails with this message.","triggerScenarios":"A config field validated with a ClassValidator constructed as new ClassValidator(SomeInterface.class) is set to a class name (e.g. \"com.example.MyCodec\") whose loaded Class object fails the SomeInterface.class.isAssignableFrom check — i.e. the class exists but does not implement the required interface.","commonSituations":"Typo-ed or stale config pointing at a class that used to implement the interface but was refactored; user supplies a concrete class instead of an implementation of the required interface; multiple versions of a jar on the classpath where the deployed version lacks the interface.","solutions":["Make the configured class implement/extend the required interface (check the interface name in the message) and rebuild/redeploy it.","Verify the fully-qualified class name in the config is the correct implementation, not a similar-looking class.","Check for duplicate/old jars on the classpath so the loaded version of the class actually implements the interface.","Pre-validate the class before writing it into config (see validationCode)."],"exampleFix":"// before: config value that does not implement the interface\nmyCodec = com.example.PlainObject  // PlainObject does not implement Codec\n// after\nmyCodec = com.example.MyCodecImpl  // class MyCodecImpl implements Codec {}","handlingStrategy":"validation","validationCode":"boolean implementsRequired(String className, Class<?> required) {\n    try {\n        Class<?> c = Class.forName(className, false,\n            Thread.currentThread().getContextClassLoader());\n        return required.isAssignableFrom(c);\n    } catch (ClassNotFoundException e) {\n        return false;\n    }\n}\n// call before setting config: implementsRequired(\"com.example.MyCodec\", Codec.class)","typeGuard":null,"tryCatchPattern":"try {\n    validator.validateField(\"myCodec\", className);\n} catch (IllegalArgumentException e) {\n    log.error(\"Configured class {} does not implement the required interface\", className, e);\n    throw new ConfigurationException(e.getMessage(), e);\n}","preventionTips":["Add a startup smoke test that validates all class-name config fields before service traffic.","Keep implementation and interface in the same shipped artifact to avoid version skew.","Document the required interface next to each class-name config key.","Run ./gradlew sanityCheck or equivalent to catch classpath drift early."],"tags":["java","config-validation","classloader","illegal-argument"],"backgroundTag":"config-class-does-not-implement-interface","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}