mybatis/mybatis-3 · error · CacheException

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

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.

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)

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.