{"record":{"id":"1901fcda2aefbf03","repo":"mybatis/mybatis-3","slug":"cannot-enable-lazy-loading-because-javassist-is-no","errorCode":null,"errorMessage":"Cannot enable lazy loading because Javassist is not available. Add Javassist to your classpath.","messagePattern":"Cannot enable lazy loading because Javassist is not available\\. Add Javassist to your classpath\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/apache/ibatis/executor/loader/javassist/JavassistProxyFactory.java","lineNumber":55,"sourceCode":"import org.apache.ibatis.reflection.ExceptionUtil;\nimport org.apache.ibatis.reflection.factory.ObjectFactory;\nimport org.apache.ibatis.reflection.property.PropertyCopier;\nimport org.apache.ibatis.reflection.property.PropertyNamer;\nimport org.apache.ibatis.session.Configuration;\n\n/**\n * @author Eduardo Macarron\n */\npublic class JavassistProxyFactory implements org.apache.ibatis.executor.loader.ProxyFactory {\n\n  private static final String FINALIZE_METHOD = \"finalize\";\n  private static final String WRITE_REPLACE_METHOD = \"writeReplace\";\n\n  public JavassistProxyFactory() {\n    try {\n      Resources.classForName(\"javassist.util.proxy.ProxyFactory\");\n    } catch (Throwable e) {\n      throw new IllegalStateException(\n          \"Cannot enable lazy loading because Javassist is not available. Add Javassist to your classpath.\", e);\n    }\n  }\n\n  @Override\n  public Object createProxy(Object target, ResultLoaderMap lazyLoader, Configuration configuration,\n      ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {\n    return EnhancedResultObjectProxyImpl.createProxy(target, lazyLoader, configuration, objectFactory,\n        constructorArgTypes, constructorArgs);\n  }\n\n  public Object createDeserializationProxy(Object target, Map<String, ResultLoaderMap.LoadPair> unloadedProperties,\n      ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {\n    return EnhancedDeserializationProxyImpl.createProxy(target, unloadedProperties, objectFactory, constructorArgTypes,\n        constructorArgs);\n  }\n\n  static Object createStaticProxy(Class<?> type, MethodHandler callback, List<Class<?>> constructorArgTypes,","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/mybatis/mybatis-3/blob/008069adb1b089579b5dcba87ee591908b263274/src/main/java/org/apache/ibatis/executor/loader/javassist/JavassistProxyFactory.java#L37-L73","documentation":"JavassistProxyFactory's constructor verifies javassist.util.proxy.ProxyFactory is loadable; if the Javassist jar is not on the classpath it throws IllegalStateException. Javassist ships as an optional dependency of MyBatis and is the default proxy factory used for lazy loading since 3.5.10 (and the only supported one going forward).","triggerScenarios":"Instantiating JavassistProxyFactory (the default when lazyLoadingEnabled=true, or explicitly via configuration.setProxyFactory) in a deployment where org.javassist:javassist is missing — slimmed-down classpaths, some OSGi containers, exclusion of transitive optional dependencies.","commonSituations":"Maven/Gradle excluding optional dependencies; fat-jar shading that drops optional jars; running only mybatis.jar without its optional proxies; deploying on containers that prune 'provided/optional' scopes.","solutions":["Add org.javassist:javassist to the runtime classpath (align with the version MyBatis's pom marks optional)","Verify with a dependency tree that no exclusion removed javassist transitively","Alternatively disable lazy loading (lazyLoadingEnabled=false) if eager fetching is acceptable — then no proxy factory is needed"],"exampleFix":"<!-- before: mybatis alone, javassist pruned -->\n<dependency>\n  <groupId>org.mybatis</groupId>\n  <artifactId>mybatis</artifactId>\n  <version>3.5.x</version>\n  <exclusions><exclusion><groupId>org.javassist</groupId><artifactId>javassist</artifactId></exclusion></exclusions>\n</dependency>\n<!-- after -->\n<dependency>\n  <groupId>org.mybatis</groupId>\n  <artifactId>mybatis</artifactId>\n  <version>3.5.x</version>\n</dependency>\n<dependency>\n  <groupId>org.javassist</groupId>\n  <artifactId>javassist</artifactId>\n  <version>3.29.0-GA</version>\n</dependency>","handlingStrategy":"validation","validationCode":"try { Class.forName(\"javassist.util.proxy.ProxyFactory\"); } catch (ClassNotFoundException e) { throw new IllegalStateException(\"javassist missing: lazy loading unavailable\", e); }","typeGuard":"static boolean javassistAvailable() { try { Class.forName(\"javassist.util.proxy.ProxyFactory\"); return true; } catch (ClassNotFoundException e) { return false; } }","tryCatchPattern":"try { sqlSessionFactory.getConfiguration().setProxyFactory(new JavassistProxyFactory()); } catch (IllegalStateException e) { throw new IllegalStateException(\"Add org.javassist:javassist to the runtime classpath\", e); }","preventionTips":["Check the dependency tree for pruned optional javassist","Smoke-test SqlSessionFactory creation in a boot health check","Keep mybatis and its optional proxy deps version-aligned"],"tags":["mybatis","lazy-loading","javassist","classpath","dependency"],"backgroundTag":null,"analyzedSha":"008069adb1b089579b5dcba87ee591908b263274","analyzedAt":"2026-08-14T13:07:10.264Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}