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

  1. Use the fully qualified class name (package + class) in the filter attribute, e.g. org.languagetool.rules.en.MyFilter.
  2. Verify the spelling of package and class name against the actual source file.
  3. Make sure the JAR containing the filter class is on the runtime classpath of the LanguageTool process (server, command line, or embedded).
  4. If the class exists only in src/test, move it to a main source set or a shipped module.
  5. 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

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


AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06). Data as JSON: /api/errors/308dbb2c998dfa1f. Report an issue: GitHub.