{"record":{"id":"cab104370b96154b","repo":"NationalSecurityAgency/ghidra","slug":"editor-class-must-have-accessible-default-construc","errorCode":null,"errorMessage":"editor class must have accessible default constructor","messagePattern":"editor class must have accessible default constructor","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/ProposedUtils/src/main/java/ghidra/framework/options/AutoOptions.java","lineNumber":161,"sourceCode":"\t\t\tif (type == OptionType.NO_TYPE) {\n\t\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\t\"Could not determine option type from default value: \" + f + \" = \" +\n\t\t\t\t\t\tdefaultValue);\n\t\t\t}\n\n\t\t\tString description = annotation.description();\n\t\t\tClass<? extends PropertyEditor> editorClass = annotation.editor();\n\t\t\tfinal PropertyEditor editor;\n\t\t\tif (editorClass == PropertyEditor.class || SystemUtilities.isInHeadlessMode()) {\n\t\t\t\teditor = null;\n\t\t\t}\n\t\t\telse {\n\t\t\t\ttry {\n\t\t\t\t\teditor = editorClass.getConstructor().newInstance();\n\t\t\t\t}\n\t\t\t\tcatch (InstantiationException | IllegalAccessException | IllegalArgumentException\n\t\t\t\t\t\t| InvocationTargetException | NoSuchMethodException | SecurityException e) {\n\t\t\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\t\t\"editor class must have accessible default constructor\", e);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (defaultValue instanceof GColor gColor) {\n\t\t\t\toptions.registerThemeColorBinding(key.name, gColor.getId(), help, description);\n\t\t\t}\n\t\t\t/*\n\t\t\telse if ( is font option ) {\n\t\t\t\n\t\t\t\t// Note: there is no font value to check against for fonts in the new Theme system.\n\t\t\t\t// If annotation fonts are needed, then they should be bound by String id.  Likely,\n\t\t\t\t// annotation fonts are not needed now that have themes.  We also probably no\n\t\t\t\t// longer need annotation colors either.\n\t\t\t\n\t\t\t\toptions.registerThemeFontBinding(description, fontId, help, description);\n\t\t\t}\n\t\t\t*/","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/framework/options/AutoOptions.java#L143-L179","documentation":"Thrown by AutoOptions.registerOptionsDefined() when the PropertyEditor class specified in an @AutoOptionDefined(editor=...) annotation cannot be instantiated via a public no-arg constructor. The framework reflectively calls getConstructor().newInstance(), so editors must be instantiable with zero arguments. This is skipped in headless mode (where editors are not used).","triggerScenarios":"Specifying an editor class with no default constructor, a private no-arg constructor, an abstract editor class, or a class that throws from its constructor. In headless mode the check is bypassed, so this only fires in GUI mode.","commonSituations":"Reusing a third-party PropertyEditor that requires constructor arguments; marking the no-arg constructor private for encapsulation; passing an interface or abstract class as the editor; an editor whose initializer needs resources unavailable in GUI mode.","solutions":["Add a public no-arg constructor to the editor class.","Ensure editor() references a concrete (non-abstract) class.","If the editor needs configuration, initialize it lazily via a property setter rather than constructor args.","Omit editor() (defaults to PropertyEditor.class) if a custom editor is not required."],"exampleFix":"// before\npublic class MyEditor extends PropertyEditorSupport {\n  public MyEditor(String config) { ... } // only non-default ctor\n}\n@AutoOptionDefined(editor = MyEditor.class, ...)\n\n// after\npublic class MyEditor extends PropertyEditorSupport {\n  public MyEditor() { this(\"default\"); }\n  public MyEditor(String config) { ... }\n}","handlingStrategy":"validation","validationCode":"Class<? extends PropertyEditor> ec = annotation.editor();\nif (ec != PropertyEditor.class && !SystemUtilities.isInHeadlessMode()) {\n  try { ec.getConstructor(); }\n  catch (NoSuchMethodException nsme) {\n    throw new IllegalStateException(\"Editor \" + ec + \" lacks a public no-arg ctor\");\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Give every custom PropertyEditor a public no-arg constructor.","Omit editor() when a custom editor is not needed.","Test option registration in GUI (non-headless) mode to exercise the editor path."],"tags":["ghidra","options","property-editor","reflection"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}