{"record":{"id":"2dbc3f8cd035c42a","repo":"languagetool-org/languagetool","slug":"could-not-create-filter-class-using-constructor-2dbc3f","errorCode":null,"errorMessage":"Could not create filter class using constructor ${constructor}","messagePattern":"Could not create filter class using constructor (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"languagetool-core/src/main/java/org/languagetool/rules/patterns/RuleFilterCreator.java","lineNumber":64,"sourceCode":"      return myFilterCache.computeIfAbsent(aClass, clazz -> {\n        Constructor<?>[] constructors = clazz.getConstructors();\n        if (constructors.length != 1) {\n          throw new RuntimeException(\"Constructor of filter class '\"\n            + className + \"' must have exactly one constructor, but it has \" + constructors.length);\n        }\n        Constructor<?> constructor = constructors[0];\n        try {\n          if (constructor.getParameterTypes().length != 0) {\n            throw new RuntimeException(\"Constructor of filter class '\" + className + \"' must not have arguments: \" + constructor);\n          }\n          Object filter = constructor.newInstance();\n          if (filter instanceof RuleFilter) {\n            return (RuleFilter) filter;\n          } else {\n            throw new RuntimeException(\"Filter class '\" + className + \"' must implement interface \" + RuleFilter.class.getSimpleName());\n          }\n        } catch (Exception e) {\n          throw new RuntimeException(\"Could not create filter class using constructor \" + constructor, e);\n        }\n      });\n    } catch (ClassNotFoundException e) {\n      throw new RuntimeException(\"Could not find filter class: '\"\n              + className + \"' - make sure to use a fully qualified class name like 'org.languagetool.rules.MyFilter'\");\n    }\n  }\n\n  public static @NotNull RuleFilterCreator getInstance() {\n    return INSTANCE;\n  }\n}\n","sourceCodeStart":46,"sourceCodeEnd":77,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-core/src/main/java/org/languagetool/rules/patterns/RuleFilterCreator.java#L46-L77","documentation":"RuleFilterCreator.getFilter wraps any exception thrown while reflectively invoking the filter's no-arg constructor (or the instanceof check path) in a RuntimeException with the message 'Could not create filter class using constructor <constructor>' plus the original exception as cause. This means the class was found and loaded but instantiation failed.","triggerScenarios":"Calling getFilter(className) where the class's no-arg constructor throws (IllegalAccessException because the class/constructor is not public, InstantiationException for abstract classes/interfaces, or an arbitrary exception thrown inside the constructor body).","commonSituations":"Filter class declared abstract or as an interface; constructor not public; constructor performs initialization that throws (bad static config, missing resource); wrong class name resolving to a different class with a throwing constructor; class compiled against an incompatible LanguageTool version so static init fails.","solutions":["Inspect the 'Caused by' of this exception — it contains the real reason (IllegalAccess, Instantiation, or the exception thrown in the constructor) and fix that.","Make the filter class public with an explicit public no-argument constructor: `public MyFilter() {}`.","Remove or fix code in the constructor that can throw; RuleFilter implementations should be cheap to construct and do work in acceptRuleMatch instead.","Ensure the class is concrete (not abstract, not an interface).","Check classpath/version consistency between languagetool-core and the module providing the filter."],"exampleFix":"// before\nclass MyFilter {\n  private MyFilter() { loadConfig(); } // throws\n}\n// after\npublic class MyFilter implements RuleFilter {\n  public MyFilter() { }\n  @Override\n  public RuleMatch acceptRuleMatch(RuleMatch match, Map<String,String> args, int pos, AnalyzedTokenReadings[] tokens) { ... }\n}","handlingStrategy":"try-catch","validationCode":"Class<?> cls = Class.forName(fqcn);\nint mods = cls.getModifiers();\nif (Modifier.isAbstract(mods) || cls.isInterface() || !Modifier.isPublic(mods)) {\n  throw new IllegalArgumentException(fqcn + \" must be a public concrete class\");\n}\ncls.getDeclaredConstructor(); // requires a no-arg constructor\nif (Modifier.isPublic(cls.getDeclaredConstructor().getModifiers())) {\n  // ok\n}","typeGuard":null,"tryCatchPattern":"try {\n  RuleFilter f = RuleFilterCreator.getInstance().getFilter(fqcn);\n} catch (RuntimeException e) {\n  log.error(\"Instantiation failed for {}\", fqcn, e.getCause());\n  throw e;\n}","preventionTips":["Keep filter constructors public, empty, and side-effect free.","Do work lazily in acceptRuleMatch, not in the constructor.","Read the 'Caused by' chain first — this error always wraps the real cause.","Align languagetool-core versions across modules to avoid NoClassDefFound during construction."],"tags":["java","reflection","instantiation","language-tool"],"backgroundTag":"invalid-constructor-argument","analyzedSha":"2e990059ce67d5e2a0f7f7ca5d31160c6709df4b","analyzedAt":"2026-09-06T09:20:17.015Z","contentChangedAt":"2026-09-06T09:20:17.015Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}