languagetool-org/languagetool · error · RuntimeException

Could not create filter class using constructor ${constructo

Error message

Could not create filter class using constructor ${constructor}

What it means

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.

Source

Thrown at languagetool-core/src/main/java/org/languagetool/rules/patterns/RuleFilterCreator.java:64

      return myFilterCache.computeIfAbsent(aClass, clazz -> {
        Constructor<?>[] constructors = clazz.getConstructors();
        if (constructors.length != 1) {
          throw new RuntimeException("Constructor of filter class '"
            + 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. Inspect the 'Caused by' of this exception — it contains the real reason (IllegalAccess, Instantiation, or the exception thrown in the constructor) and fix that.
  2. Make the filter class public with an explicit public no-argument constructor: `public MyFilter() {}`.
  3. Remove or fix code in the constructor that can throw; RuleFilter implementations should be cheap to construct and do work in acceptRuleMatch instead.
  4. Ensure the class is concrete (not abstract, not an interface).
  5. Check classpath/version consistency between languagetool-core and the module providing the filter.

Example fix

// before
class MyFilter {
  private MyFilter() { loadConfig(); } // throws
}
// after
public class MyFilter implements RuleFilter {
  public MyFilter() { }
  @Override
  public RuleMatch acceptRuleMatch(RuleMatch match, Map<String,String> args, int pos, AnalyzedTokenReadings[] tokens) { ... }
}
Defensive patterns

Strategy: try-catch

Validate before calling

Class<?> cls = Class.forName(fqcn);
int mods = cls.getModifiers();
if (Modifier.isAbstract(mods) || cls.isInterface() || !Modifier.isPublic(mods)) {
  throw new IllegalArgumentException(fqcn + " must be a public concrete class");
}
cls.getDeclaredConstructor(); // requires a no-arg constructor
if (Modifier.isPublic(cls.getDeclaredConstructor().getModifiers())) {
  // ok
}

Try / catch

try {
  RuleFilter f = RuleFilterCreator.getInstance().getFilter(fqcn);
} catch (RuntimeException e) {
  log.error("Instantiation failed for {}", fqcn, e.getCause());
  throw e;
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


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