{"record":{"id":"85648375efcfb0f9","repo":"apache/cassandra","slug":"cannot-access-method-validateoptions-in","errorCode":null,"errorMessage":"Cannot access method validateOptions in ","messagePattern":"Cannot access method validateOptions in ","errorType":"validation","errorClass":"ConfigurationException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/schema/CompactionParams.java","lineNumber":227,"sourceCode":"        }\n        catch (InvocationTargetException e)\n        {\n            if (e.getTargetException() instanceof ConfigurationException)\n                throw (ConfigurationException) e.getTargetException();\n\n            Throwable cause = e.getCause() == null\n                            ? e\n                            : e.getCause();\n\n            throw new ConfigurationException(format(\"%s.validateOptions() threw an error: %s %s\",\n                                                    klass.getName(),\n                                                    cause.getClass().getName(),\n                                                    cause.getMessage()),\n                                             e);\n        }\n        catch (IllegalAccessException e)\n        {\n            throw new ConfigurationException(\"Cannot access method validateOptions in \" + klass.getName(), e);\n        }\n\n        String minThreshold = options.get(Option.MIN_THRESHOLD.toString());\n        if (minThreshold != null && !StringUtils.isNumeric(minThreshold))\n        {\n            throw new ConfigurationException(format(\"Invalid value %s for '%s' compaction sub-option - must be an integer\",\n                                                    minThreshold,\n                                                    Option.MIN_THRESHOLD));\n        }\n\n        String maxThreshold = options.get(Option.MAX_THRESHOLD.toString());\n        if (maxThreshold != null && !StringUtils.isNumeric(maxThreshold))\n        {\n            throw new ConfigurationException(format(\"Invalid value %s for '%s' compaction sub-option - must be an integer\",\n                                                    maxThreshold,\n                                                    Option.MAX_THRESHOLD));\n        }\n","sourceCodeStart":209,"sourceCodeEnd":245,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/schema/CompactionParams.java#L209-L245","documentation":"CompactionParams.validate() catches IllegalAccessException from the reflective invocation of the strategy class's static validateOptions(Map) and rethrows it as a ConfigurationException saying the method cannot be accessed. This happens when the method exists but is not accessible via reflection (non-public or in a restricted package/module).","triggerScenarios":"Using a custom compaction strategy whose validateOptions(Map) is not declared public static, or a strategy loaded from a restricted classloader/module that blocks reflective access.","commonSituations":"Third-party/custom compaction strategies missing the public modifier; strategies compiled against different visibility; Java module restrictions when loading custom classes.","solutions":["Declare the method exactly as public static Map<String, String> validateOptions(Map<String, String> options) in your strategy class.","Rebuild and redeploy the custom strategy JAR with the corrected signature/visibility.","If module access restrictions apply, open the package (e.g. --add-opens) or avoid restricted classloading for strategies.","Prefer subclassing a built-in strategy so the inherited public validateOptions is used."],"exampleFix":"// before\nclass MyStrategy extends SizeTieredCompactionStrategy {\n    static Map<String, String> validateOptions(Map<String, String> options) { ... }\n}\n// after\nclass MyStrategy extends SizeTieredCompactionStrategy {\n    public static Map<String, String> validateOptions(Map<String, String> options) { ... }\n}","handlingStrategy":"type-guard","validationCode":"Method m = strategyClass.getMethod(\"validateOptions\", Map.class);\nif (!java.lang.reflect.Modifier.isPublic(m.getModifiers()))\n    throw new IllegalArgumentException(\"validateOptions must be public static\");","typeGuard":"boolean validStrategyClass(Class<?> c) {\n    try { return java.lang.reflect.Modifier.isPublic(c.getMethod(\"validateOptions\", Map.class).getModifiers()); }\n    catch (NoSuchMethodException e) { return false; }\n}","tryCatchPattern":"try { applyCompaction(opts); } catch (ConfigurationException e) {\n    if (e.getMessage().startsWith(\"Cannot access method validateOptions\"))\n        logger.error(\"Custom strategy {} has non-public validateOptions\", e.getMessage());\n}","preventionTips":["Declare custom strategies' validateOptions as public static.","Test-load custom strategy classes before deploying to production.","Prefer subclassing built-in strategies to inherit correct visibility."],"tags":["cassandra","reflection","compaction","accessibility"],"backgroundTag":"method-not-implemented","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}