mybatis/mybatis-3 · error · CacheException

Could not instantiate cache implementation

Error message

Could not instantiate cache implementation ({}). Cause: {}

What it means

CacheBuilder.newBaseCacheInstance() throws CacheException when the base cache class's constructor Cache(String id) was found but Constructor.newInstance(id) failed — the constructor threw, the class is abstract, or access failed. The cacheClass is named in the message and the original exception is chained.

Solutions

  1. Check the chained cause for the exact constructor failure and fix it inside the cache class.
  2. Make the constructor trivial: only store the id; do connections/initialization lazily or in initialize() via InitializingObject.
  3. Confirm the class is concrete and public with a public Cache(String id) constructor.

Example fix

// before
public class MyCache implements Cache {
  public MyCache(String id) {
    this.client = RedisClient.connect(id); // throws if server down -> build fails
  }
}

// after
public class MyCache implements Cache {
  private Client client;
  public MyCache(String id) { this.id = id; }
  private Client client() {
    if (client == null) client = RedisClient.connect(id); // lazy
    return client;
  }
}
Defensive patterns

Strategy: validation

Validate before calling

// Assert the contract before registering the cache
Class<? extends Cache> c = MyCache.class;
if (java.lang.reflect.Modifier.isAbstract(c.getModifiers())) {
  throw new IllegalStateException(c + " must be concrete");
}
c.getConstructor(String.class); // throws clearly if missing
new CacheBuilder(id).implementation(c).build();

Prevention

When it happens

Trigger: Specifying <cache type="com.x.MyCache"/> where MyCache(String id) throws (e.g. it tries to connect to an external system or reads config that is missing); the class is abstract; or the constructor does something illegal (e.g. spawns threads that fail).

Common situations: Custom cache implementations doing heavy work in the constructor; abstract cache classes referenced by mistake; constructor logic depending on containers/resources not yet available at SqlSessionFactory build time.

Related errors


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

Appendix: source

Thrown at src/main/java/org/apache/ibatis/mapping/CacheBuilder.java:187

        }
      }
    }
    if (InitializingObject.class.isAssignableFrom(cache.getClass())) {
      try {
        ((InitializingObject) cache).initialize();
      } catch (Exception e) {
        throw new CacheException(
            "Failed cache initialization for '" + cache.getId() + "' on '" + cache.getClass().getName() + "'", e);
      }
    }
  }

  private Cache newBaseCacheInstance(Class<? extends Cache> cacheClass, String id) {
    Constructor<? extends Cache> cacheConstructor = getBaseCacheConstructor(cacheClass);
    try {
      return cacheConstructor.newInstance(id);
    } catch (Exception e) {
      throw new CacheException("Could not instantiate cache implementation (" + cacheClass + "). Cause: " + e, e);
    }
  }

  private Constructor<? extends Cache> getBaseCacheConstructor(Class<? extends Cache> cacheClass) {
    try {
      return cacheClass.getConstructor(String.class);
    } catch (Exception e) {
      throw new CacheException("Invalid base cache implementation (" + cacheClass + ").  "
          + "Base cache implementations must have a constructor that takes a String id as a parameter.  Cause: " + e,
          e);
    }
  }

  private Cache newCacheDecoratorInstance(Class<? extends Cache> cacheClass, Cache base) {
    Constructor<? extends Cache> cacheConstructor = getCacheDecoratorConstructor(cacheClass);
    try {
      return cacheConstructor.newInstance(base);
    } catch (Exception e) {

View on GitHub (pinned to 008069adb1)