baomidou/mybatis-plus · error · ClassNotFoundException

Cannot find class: {}

Error message

Cannot find class: {}

What it means

ClassUtils.loadClass iterates every supplied ClassLoader and calls Class.forName(className, true, classLoader). If none of them can resolve the class, a ClassNotFoundException with the message 'Cannot find class: <name>' is thrown. This is the terminal failure of mybatis-plus's class resolution utility, used when the framework reflectively loads classes named in configuration (e.g. type handlers, entity classes, interceptors).

Source

Thrown at mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/toolkit/ClassUtils.java:185

    public static Class<?> toClassConfident(String name, ClassLoader classLoader) {
        try {
            return loadClass(name, getClassLoaders(classLoader));
        } catch (ClassNotFoundException e) {
            throw ExceptionUtils.mpe("找不到指定的class!请仅在明确确定会有 class 的时候,调用该方法", e);
        }
    }

    private static Class<?> loadClass(String className, ClassLoader[] classLoaders) throws ClassNotFoundException {
        for (ClassLoader classLoader : classLoaders) {
            if (classLoader != null) {
                try {
                    return Class.forName(className, true, classLoader);
                } catch (ClassNotFoundException e) {
                    // ignore
                }
            }
        }
        throw new ClassNotFoundException("Cannot find class: " + className);
    }


    /**
     * Determine the name of the package of the given class,
     * e.g. "java.lang" for the {@code java.lang.String} class.
     *
     * @param clazz the class
     * @return the package name, or the empty String if the class
     * is defined in the default package
     */
    public static String getPackageName(Class<?> clazz) {
        Assert.notNull(clazz, "Class must not be null");
        return getPackageName(clazz.getName());
    }

    /**
     * Determine the name of the package of the given fully-qualified class name,

View on GitHub (pinned to bf67d90747)

Solutions

  1. Verify the fully-qualified class name string is spelled correctly and matches the actual package (watch out for shading/relocation prefixes).
  2. Confirm the jar containing the class is on the runtime classpath of the module that performs the reflective load.
  3. In container/classloader-mismatch situations, set Thread.currentThread().setContextClassLoader(targetClassLoader) before the mybatis-plus call so the context loader can resolve the class.
  4. Reproduce with Class.forName(name) in the same deployment to prove it is a classpath/classloader problem and not a mybatis-plus bug.

Example fix

// before: class only visible to app classloader, context loader misses it
String name = "com.acme.biz.CustomTypeHandler";
Class<?> clazz = ClassUtils.toClassConfident(name); // ClassNotFoundException

// after: align the context classloader before resolution
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
Class<?> clazz = ClassUtils.toClassConfident(name);
Defensive patterns

Strategy: validation

Validate before calling

String name = "com.acme.biz.Thing";
boolean resolvable;
try {
    Class.forName(name, true, Thread.currentThread().getContextClassLoader());
    resolvable = true;
} catch (ClassNotFoundException e) {
    resolvable = false;
}
if (!resolvable) { /* fix classpath/classloader before proceeding */ }

Try / catch

try {
    Class<?> clazz = ClassUtils.toClassConfident(name);
} catch (ClassNotFoundException e) {
    throw new IllegalStateException("Class not on runtime classpath: " + name
        + " — check dependencies and context classloader", e);
}

Prevention

When it happens

Trigger: Calling ClassUtils.toClassConfident(name) / loadClass with a fully-qualified class name that is not on any of the candidate classloaders (context classloader, ClassUtils's own classloader). Typical entry points: specifying a nonexistent className in mybatis-plus configuration, entity scanning resolving a class name built from a table name, or running in an environment (OSGi, war on some servers, fat-jar relocations) where the context classloader cannot see application classes.

Common situations: Typos in configured class names; shaded/relocated jars where the package prefix changed; complex containers (Tomcat war deployment, Spring Boot executable jar with custom launcher) where Thread.currentThread().getContextClassLoader() differs from the classloader that loaded mybatis-plus; missing dependency on the classpath.

Related errors


AI-assisted analysis of baomidou/mybatis-plus@bf67d90747 (2026-08-14). Data as JSON: /api/errors/6a6ba8f01fe221f3. Report an issue: GitHub.