{"record":{"id":"8e3f07358373ee92","repo":"apache/cassandra","slug":"cannot-use-abstract-class-s-as-s","errorCode":null,"errorMessage":"Cannot use abstract class '%s' as %s.","messagePattern":"Cannot use abstract class '(.+?)' as (.+?)\\.","errorType":"exception","errorClass":"ConfigurationException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/utils/FBUtilities.java","lineNumber":908,"sourceCode":"    public static <T> T construct(String classname, String readable, Class<T> expectedType) throws ConfigurationException\n    {\n        Class<? extends T> cls = FBUtilities.classForNameWithoutInitialization(classname, readable, expectedType);\n        return construct(cls, classname, readable);\n    }\n\n    private static <T> T construct(Class<? extends T> cls, String classname, String readable) throws ConfigurationException\n    {\n        try\n        {\n            return cls.newInstance();\n        }\n        catch (IllegalAccessException e)\n        {\n            throw new ConfigurationException(String.format(\"Default constructor for %s class '%s' is inaccessible.\", readable, classname));\n        }\n        catch (InstantiationException e)\n        {\n            throw new ConfigurationException(String.format(\"Cannot use abstract class '%s' as %s.\", classname, readable));\n        }\n        catch (Exception e)\n        {\n            // Catch-all because Class.newInstance() \"propagates any exception thrown by the nullary constructor, including a checked exception\".\n            if (e.getCause() instanceof ConfigurationException)\n                throw (ConfigurationException)e.getCause();\n            throw new ConfigurationException(String.format(\"Error instantiating %s class '%s'.\", readable, classname), e);\n        }\n    }\n\n    public static <T> NavigableSet<T> singleton(T column, Comparator<? super T> comparator)\n    {\n        NavigableSet<T> s = new TreeSet<T>(comparator);\n        s.add(column);\n        return s;\n    }\n\n    public static <T> NavigableSet<T> emptySortedSet(Comparator<? super T> comparator)","sourceCodeStart":890,"sourceCodeEnd":926,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/utils/FBUtilities.java#L890-L926","documentation":"Same reflective construction path (constructorForName/Class.newInstance): if instantiation fails with InstantiationException, the configured class is abstract or an interface, so a ConfigurationException 'Cannot use abstract class ... as %s' is thrown. A catch-all also unwraps exceptions thrown by the constructor itself, rethrowing a nested ConfigurationException directly.","triggerScenarios":"Configuring an abstract class or interface as a pluggable implementation, or the plugin's constructor throwing any exception during newInstance() (checked exceptions are propagated by Class.newInstance()).","commonSituations":"Pointing config at a base/abstract class instead of a concrete implementation; interface name typo-direction (listing the interface rather than an impl); plugin constructor throwing due to bad init (e.g. cannot open file).","solutions":["Configure a concrete (non-abstract) implementation class of the plugin interface","If the chained cause is a constructor exception, fix the root problem it reports","Verify with `javap` or IDE that the class is concrete and instantiable","Upgrade custom code if it became abstract after a refactor"],"exampleFix":"// before\nclass_name: org.apache.cassandra.security.AbstractCryptoProvider  // abstract\n// after\nclass_name: org.apache.cassandra.security.DefaultCryptoProvider","handlingStrategy":"validation","validationCode":"boolean isConcreteInstantiable(String cn) {\n    try { Class<?> c = Class.forName(cn);\n          return !c.isInterface() && !java.lang.reflect.Modifier.isAbstract(c.getModifiers()); }\n    catch (Throwable t) { return false; }\n}\n// guard: if (!isConcreteInstantiable(className)) failFast();","typeGuard":null,"tryCatchPattern":"try {\n    Object plugin = FBUtilities.constructorForName(className, readable);\n} catch (ConfigurationException e) {\n    if (e.getCause() instanceof ConfigurationException)\n        logger.error(\"Plugin constructor reported config error\", e.getCause());\n    else if (e.getMessage() != null && e.getMessage().contains(\"abstract\"))\n        logger.error(\"Configure a concrete implementation, not \" + className);\n    throw e;\n}","preventionTips":["Never list abstract base classes or interfaces as config implementations","Unwrap the cause chain — constructor-thrown ConfigurationExceptions are rethrown directly","Keep plugin constructors free of throwing initialization, or handle it explicitly","Document which concrete class names are valid for each config key"],"tags":["reflection","constructor","abstract-class"],"backgroundTag":"abstract-method-not-implemented","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}