{"record":{"id":"aa386be35a134db2","repo":"apache/cassandra","slug":"invalid-comparator-class-s-must-define-a-public","errorCode":null,"errorMessage":"Invalid comparator class %s: must define a public static instance field or a public static method getInstance(TypeParser).","messagePattern":"Invalid comparator class (.+?): must define a public static instance field or a public static method getInstance\\(TypeParser\\)\\.","errorType":"validation","errorClass":"ConfigurationException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/db/marshal/TypeParser.java","lineNumber":514,"sourceCode":"        // access or getInstance(TypeParser) invocation below performs the initialization for valid types.\n        @SuppressWarnings(\"unchecked\")\n        Class<? extends AbstractType<?>> typeClass =\n            (Class<? extends AbstractType<?>>) FBUtilities.classForNameWithoutInitialization(className,\n                                                                                             \"abstract-type\",\n                                                                                             AbstractType.class);\n        return typeClass;\n    }\n\n    private static AbstractType<?> getRawAbstractType(Class<? extends AbstractType<?>> typeClass) throws ConfigurationException\n    {\n        try\n        {\n            Field field = typeClass.getDeclaredField(\"instance\");\n            return (AbstractType<?>) field.get(null);\n        }\n        catch (NoSuchFieldException | IllegalAccessException e)\n        {\n            throw new ConfigurationException(\"Invalid comparator class \" + typeClass.getName() + \": must define a public static instance field or a public static method getInstance(TypeParser).\");\n        }\n    }\n\n    private static AbstractType<?> getRawAbstractType(Class<? extends AbstractType<?>> typeClass, TypeParser parser) throws ConfigurationException\n    {\n        try\n        {\n            Method method = typeClass.getDeclaredMethod(\"getInstance\", TypeParser.class);\n            return (AbstractType<?>) method.invoke(null, parser);\n        }\n        catch (NoSuchMethodException | IllegalAccessException e)\n        {\n            throw new ConfigurationException(\"Invalid comparator class \" + typeClass.getName() + \": must define a public static instance field or a public static method getInstance(TypeParser).\");\n        }\n        catch (InvocationTargetException e)\n        {\n            ConfigurationException ex = new ConfigurationException(\"Invalid definition for comparator \" + typeClass.getName() + \".\");\n            ex.initCause(e.getTargetException());","sourceCodeStart":496,"sourceCodeEnd":532,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/db/marshal/TypeParser.java#L496-L532","documentation":"TypeParser.getRawAbstractType(Class) instantiates an AbstractType via its public static 'instance' field when no getInstance(TypeParser) method exists. This ConfigurationException is thrown when the class has neither — the comparator class doesn't follow the AbstractType singleton/instance convention required by the parser.","triggerScenarios":"Parsing a type name whose class (custom or built-in) lacks both a declared static Field named 'instance' and a static getInstance(TypeParser) method — typically a custom AbstractType subclass with the singleton declared under a different field name or not static.","commonSituations":"Deploying a custom comparator class that implements neither convention, renaming the singleton field (e.g. to INSTANCE) in a custom type, classpath loading an older/newer version of a type class where the field was renamed, or referencing third-party AbstractType implementations not designed for TypeParser.","solutions":["Add a public static field named exactly 'instance' of the comparator's type to the class, or","Add a public static AbstractType getInstance(TypeParser parser) method to the class","Verify the deployed jar version matches the code you expect (the field may have been renamed upstream)","Check for classloader conflicts — two versions of the same class on the classpath","If the class is third-party, wrap it with an adapter class that exposes the 'instance' field"],"exampleFix":"// before\nclass CustomComparator extends AbstractType<ByteBuffer> { public static final CustomComparator INSTANCE = new CustomComparator(); ... }\n// after\nclass CustomComparator extends AbstractType<ByteBuffer> { public static final CustomComparator instance = new CustomComparator(); ... }","handlingStrategy":"validation","validationCode":"static <T extends AbstractType<?>> void validateComparatorClass(Class<T> clazz) throws Exception {\n    try {\n        clazz.getDeclaredField(\"instance\");\n    } catch (NoSuchFieldException e) {\n        try {\n            clazz.getDeclaredMethod(\"getInstance\", TypeParser.class);\n        } catch (NoSuchMethodException e2) {\n            throw new IllegalArgumentException(clazz.getName() + \" needs a static 'instance' field or getInstance(TypeParser) method\");\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    AbstractType<?> t = TypeParser.parse(customTypeName);\n} catch (ConfigurationException e) {\n    if (e.getMessage().startsWith(\"Invalid comparator class\"))\n        throw new SchemaConfigurationException(\"Custom comparator missing static instance/getInstance convention\", e);\n    throw e;\n}","preventionTips":["Custom AbstractType classes must expose a public static field named exactly 'instance'","Alternatively implement public static AbstractType getInstance(TypeParser parser)","Run a startup self-check that parses every registered custom comparator name"],"tags":["cassandra","type-parser","configuration-exception","reflection"],"backgroundTag":"class-not-found","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}