{"record":{"id":"8200540a8d5c675f","repo":"mybatis/mybatis-3","slug":"cannot-find-class","errorCode":null,"errorMessage":"Cannot find class: {}","messagePattern":"Cannot find class: (.+?)","errorType":"exception","errorClass":"ClassNotFoundException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/apache/ibatis/io/ClassLoaderWrapper.java","lineNumber":226,"sourceCode":"  Class<?> classForName(String name, ClassLoader[] classLoader) throws ClassNotFoundException {\n\n    for (ClassLoader cl : classLoader) {\n\n      if (null != cl) {\n\n        try {\n\n          return Class.forName(name, true, cl);\n\n        } catch (ClassNotFoundException e) {\n          // we'll ignore this until all classloaders fail to locate the class\n        }\n\n      }\n\n    }\n\n    throw new ClassNotFoundException(\"Cannot find class: \" + name);\n\n  }\n\n  ClassLoader[] getClassLoaders(ClassLoader classLoader) {\n    return new ClassLoader[] { classLoader, defaultClassLoader, Thread.currentThread().getContextClassLoader(),\n        getClass().getClassLoader(), systemClassLoader };\n  }\n\n}\n","sourceCodeStart":208,"sourceCodeEnd":236,"githubUrl":"https://github.com/mybatis/mybatis-3/blob/008069adb1b089579b5dcba87ee591908b263274/src/main/java/org/apache/ibatis/io/ClassLoaderWrapper.java#L208-L236","documentation":"ClassLoaderWrapper tries to load a class through a chain of classloaders (given loader, defaultClassLoader, context loader, mybatis's own loader, system loader); only after every one fails with ClassNotFoundException does it rethrow as 'Cannot find class: <name>'. Callers typically wrap this into their own exceptions (e.g. type alias or typeHandler resolution failures).","triggerScenarios":"Resolving a typeAlias, resultType, parameterType, or typeHandler class name from mybatis-config.xml / mapper XML where the named class is absent from every classloader in the chain — typo in the name, class not on the classpath, or isolated/war classloader setups where the class lives in a loader not in the chain.","commonSituations":"Typos in fully qualified class names in XML; class in a module/jar not included in the deployment; web/app-server deployments where the thread context classloader differs from the app classloader; hot-reload environments with stale loaders; inner classes written with '.' instead of '$' or missing package.","solutions":["Fix the class name string — verify the fully qualified name, use $ for nested classes if needed.","Ensure the containing jar/class is actually on the runtime classpath (not just compile-time).","Set Configuration.setDefaultClassLoader to the application's classloader in container environments.","In hot-reload/dev-restart setups, rebuild so freshly loaded classes are visible to the current context classloader."],"exampleFix":"<!-- before -->\n<typeAlias type=\"com.exmaple.domain.User\" alias=\"User\"/> <!-- typo: exmaple -->\n\n<!-- after -->\n<typeAlias type=\"com.example.domain.User\" alias=\"User\"/>","handlingStrategy":"validation","validationCode":"// validate every alias/type name resolves before building the session\nstatic void checkClassNames(ClassLoader cl, String... names) {\n  for (String n : names) {\n    try {\n      Class.forName(n, true, cl);\n    } catch (ClassNotFoundException e) {\n      throw new IllegalStateException(\"Type referenced in mybatis config not loadable: \" + n, e);\n    }\n  }\n}","typeGuard":"static Optional<Class<?>> tryLoad(ClassLoader cl, String fqn) {\n  try { return Optional.of(Class.forName(fqn, true, cl)); }\n  catch (ClassNotFoundException e) { return Optional.empty(); }\n}","tryCatchPattern":"catch (PersistenceException | RuntimeException e) when rootCauseIs(e, ClassNotFoundException.class) && e.getMessage().contains(\"Cannot find class\") -> report the class name and current classloader chain; treat as deployment/packaging defect, not retryable.","preventionTips":["Run a config-validation test at build time that resolves every resultType/parameterType/typeHandler named in XML.","Use $ for nested classes in XML type names and verify jars are in the runtime, not just compile, classpath."],"tags":["mybatis","classloading","classpath","configuration"],"backgroundTag":null,"analyzedSha":"008069adb1b089579b5dcba87ee591908b263274","analyzedAt":"2026-08-14T13:07:10.264Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}