{"record":{"id":"365a4fe2ccf1e93e","repo":"mybatis/mybatis-3","slug":"error-getting-mapper-instance-cause-cause","errorCode":null,"errorMessage":"Error getting mapper instance. Cause: {cause}","messagePattern":"Error getting mapper instance\\. Cause: (.+?)","errorType":"exception","errorClass":"BindingException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/apache/ibatis/binding/MapperRegistry.java","lineNumber":52,"sourceCode":"public class MapperRegistry {\n\n  private final Configuration config;\n  private final Map<Class<?>, MapperProxyFactory<?>> knownMappers = new ConcurrentHashMap<>();\n\n  public MapperRegistry(Configuration config) {\n    this.config = config;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public <T> T getMapper(Class<T> type, SqlSession sqlSession) {\n    final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);\n    if (mapperProxyFactory == null) {\n      throw new BindingException(\"Type \" + type + \" is not known to the MapperRegistry.\");\n    }\n    try {\n      return mapperProxyFactory.newInstance(sqlSession);\n    } catch (Exception e) {\n      throw new BindingException(\"Error getting mapper instance. Cause: \" + e, e);\n    }\n  }\n\n  public <T> boolean hasMapper(Class<T> type) {\n    return knownMappers.containsKey(type);\n  }\n\n  public <T> void addMapper(Class<T> type) {\n    if (type.isInterface()) {\n      if (hasMapper(type)) {\n        throw new BindingException(\"Type \" + type + \" is already known to the MapperRegistry.\");\n      }\n      boolean loadCompleted = false;\n      try {\n        knownMappers.put(type, new MapperProxyFactory<>(type));\n        // It's important that the type is added before the parser is run\n        // otherwise the binding may automatically be attempted by the\n        // mapper parser. If the type is already known, it won't try.","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/mybatis/mybatis-3/blob/008069adb1b089579b5dcba87ee591908b263274/src/main/java/org/apache/ibatis/binding/MapperRegistry.java#L34-L70","documentation":"MapperProxyFactory.newInstance() failed while creating the JDK dynamic proxy for the mapper interface. The cause is chained in the message ('Cause: ...'); typical causes are failures in instantiating the proxy, errors thrown from mapper interface default methods during construction of the invoker cache, or classloader issues in managed environments.","triggerScenarios":"Any reflective failure while building the MapperProxy: e.g. inaccessible default methods under strict module boundaries (Java 16+ strong encapsulation), a SecurityManager denying proxy creation, or classloader mismatch (mapper interface visible to a different loader than MyBatis).","commonSituations":"App servers with parent-last classloading; OSGi containers; JPMS deployments where org.apache.ibatis cannot access the mapper interface; finalizing environments where reflection is restricted.","solutions":["Read the chained 'Cause:' exception first - it names the real failure (IllegalAccessException, etc.)","For JPMS, open/export the mapper's package to org.apache.ibatis or add the needed --add-opens JVM flags","Ensure one classloader loads both mybatis and the mapper interfaces (avoid duplicated jars across webapp and container libs)"],"exampleFix":"# example JPMS fix\njava --add-opens com.example.mappers/com.example.mappers=org.apache.ibatis ...","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  FooMapper m = session.getMapper(FooMapper.class);\n} catch (BindingException e) {\n  log.error(\"Mapper proxy creation failed: {}\", e.getCause().getMessage(), e.getCause());\n  throw e; // classloader/module problems are not recoverable at runtime\n}","preventionTips":["Keep mybatis and mapper interfaces in the same classloader (no duplicated jars across webapp/container)","For JPMS deployments, add --add-opens for mapper packages","Always log the chained cause; the root reason is never the wrapper message"],"tags":["mybatis","binding","proxy","classloading"],"backgroundTag":null,"analyzedSha":"008069adb1b089579b5dcba87ee591908b263274","analyzedAt":"2026-08-14T13:07:10.264Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}