mybatis/mybatis-3 · error · ScriptingException

Failed to load language driver for " + cls.getName()

Error message

Failed to load language driver for " + cls.getName()

What it means

When a LanguageDriver class is registered by Class, the registry instantiates it reflectively via its declared no-arg constructor. If construction fails — the class has no no-arg constructor, is abstract/interface, or the constructor throws — the exception is wrapped in a ScriptingException naming the driver class. The driver must be a concrete class with a usable public/accessible no-arg constructor.

Source

Thrown at src/main/java/org/apache/ibatis/scripting/LanguageDriverRegistry.java:38

/**
 * @author Frank D. Martinez [mnesarco]
 */
public class LanguageDriverRegistry {

  private final Map<Class<? extends LanguageDriver>, LanguageDriver> languageDriverMap = new HashMap<>();

  private Class<? extends LanguageDriver> defaultDriverClass;

  public void register(Class<? extends LanguageDriver> cls) {
    if (cls == null) {
      throw new IllegalArgumentException("null is not a valid Language Driver");
    }
    languageDriverMap.computeIfAbsent(cls, k -> {
      try {
        return k.getDeclaredConstructor().newInstance();
      } catch (Exception ex) {
        throw new ScriptingException("Failed to load language driver for " + cls.getName(), ex);
      }
    });
  }

  public void register(LanguageDriver instance) {
    if (instance == null) {
      throw new IllegalArgumentException("null is not a valid Language Driver");
    }
    Class<? extends LanguageDriver> cls = instance.getClass();
    if (!languageDriverMap.containsKey(cls)) {
      languageDriverMap.put(cls, instance);
    }
  }

  public LanguageDriver getDriver(Class<? extends LanguageDriver> cls) {
    return languageDriverMap.get(cls);
  }

View on GitHub (pinned to 008069adb1)

Solutions

  1. Add a public no-arg constructor to the driver class
  2. Register a pre-built instance instead: registry.register(new MyDriver(deps)) — the instance overload skips instantiation
  3. Ensure the class is concrete (not abstract/interface) and accessible for reflective instantiation
  4. Check the wrapped cause for constructor-time failures (missing dependencies) and fix driver initialization

Example fix

// before
class MyDriver implements LanguageDriver {
  MyDriver(Config c) { ... } // only constructor -> register(MyDriver.class) throws
}

// after
registry.register(new MyDriver(config)); // register the instance
Defensive patterns

Strategy: fallback

Validate before calling

try {
  cls.getDeclaredConstructor(); // proves a no-arg constructor exists
  registry.register(cls);
} catch (NoSuchMethodException e) {
  registry.register(newInstanceSomehow(cls)); // register an instance instead
}

Try / catch

try {
  registry.register(MyDriver.class);
} catch (ScriptingException e) {
  // fall back to instance registration if you can construct it
  registry.register(new MyDriver(deps));
}

Prevention

When it happens

Trigger: register(MyDriver.class) where MyDriver only has constructor MyDriver(String); registering an abstract driver base class; a driver whose no-arg constructor throws (missing dependency, failed init); non-public class under restrictive module/access rules.

Common situations: Custom scripting language drivers with parameterized constructors; drivers with initialization that requires config passed in; JPMS/strong-encapsulation environments blocking reflective access to the constructor.

Related errors


AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14). Data as JSON: /api/errors/2f8269df1a4ade53. Report an issue: GitHub.