languagetool-org/languagetool · error · RuntimeException
Could not find filter class: '${className}' - make sure to u
Error message
Could not find filter class: '${className}' - make sure to use a fully qualified class name like 'org.languagetool.rules.MyFilter' What it means
RuleFilterCreator.getFilter catches ClassNotFoundException from Class.forName(className) and throws a RuntimeException telling you the filter class could not be found and that a fully qualified class name must be used. It means the JVM class loader could not locate the class named in the filter attribute at runtime.
Source
Thrown at languagetool-core/src/main/java/org/languagetool/rules/patterns/RuleFilterCreator.java:68
+ className + "' must have exactly one constructor, but it has " + constructors.length);
}
Constructor<?> constructor = constructors[0];
try {
if (constructor.getParameterTypes().length != 0) {
throw new RuntimeException("Constructor of filter class '" + className + "' must not have arguments: " + constructor);
}
Object filter = constructor.newInstance();
if (filter instanceof RuleFilter) {
return (RuleFilter) filter;
} else {
throw new RuntimeException("Filter class '" + className + "' must implement interface " + RuleFilter.class.getSimpleName());
}
} catch (Exception e) {
throw new RuntimeException("Could not create filter class using constructor " + constructor, e);
}
});
} catch (ClassNotFoundException e) {
throw new RuntimeException("Could not find filter class: '"
+ className + "' - make sure to use a fully qualified class name like 'org.languagetool.rules.MyFilter'");
}
}
public static @NotNull RuleFilterCreator getInstance() {
return INSTANCE;
}
}
View on GitHub (pinned to 2e990059ce)
Solutions
- Use the fully qualified class name (package + class) in the filter attribute, e.g. org.languagetool.rules.en.MyFilter.
- Verify the spelling of package and class name against the actual source file.
- Make sure the JAR containing the filter class is on the runtime classpath of the LanguageTool process (server, command line, or embedded).
- If the class exists only in src/test, move it to a main source set or a shipped module.
- Check for recent renames/moves of the class and update all rule XML references.
Example fix
<!-- before --> <filter class="MyFilter"/> <!-- after --> <filter class="org.languagetool.rules.en.MyFilter"/>
Defensive patterns
Strategy: validation
Validate before calling
try {
Class.forName(fqcn);
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException("Filter class not on classpath: " + fqcn);
} Try / catch
try {
RuleFilter f = RuleFilterCreator.getInstance().getFilter(fqcn);
} catch (RuntimeException e) {
if (e.getMessage().contains("Could not find filter class")) {
log.error("Use FQCN and ensure the JAR is on the classpath: {}", fqcn);
}
throw e;
} Prevention
- Always use the fully qualified class name in filter attributes.
- Add the module/JAR with custom filters to the runtime classpath of server or command-line runs.
- Update rule XML files whenever packages are renamed.
- Smoke-test rule loading at startup instead of only at match time.
When it happens
Trigger: Calling getFilter(className) with a class name not on the classpath: a simple name like 'MyFilter' instead of 'org.languagetool.rules.MyFilter', a typo in the package, or a JAR/module not included in the runtime classpath (e.g. missing from languagetool-commandline or the LT server's libs).
Common situations: Writing the short class name in rule XML instead of the FQCN; the filter lives in a custom extension JAR that was never added to LanguageTool's classpath; package renamed after a refactor while rule XML still references the old one; class only exists in test sources, not in the shipped artifact.
Related errors
- Filter class '${className}' must implement interface ${RuleF
- Could not create filter class using constructor ${constructo
- Invalid syntax for key/value, expected 'key:value', got: '${
- Your reference number ${refNumber} is bigger than the number
- Could not tag and disambiguate '<token>'
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/308dbb2c998dfa1f.
Report an issue: GitHub.