baomidou/mybatis-plus · error · RuntimeException

注册用户目录的xml文件失败

Error message

注册用户目录的xml文件失败

What it means

Thrown by the nested RuntimeHintsRegistrar inside MyBatisPlusNativeImageConfiguration: identical logic to MyBaitsRuntimeHintsRegistrar — it registers mapper XML resource patterns for GraalVM native images and wraps any IOException from AotUtils.findResources in RuntimeException('注册用户目录的xml文件失败' — failed to register xml files from user directories). This variant is the inner registrar used by the auto-configuration class.

Source

Thrown at spring-boot-starter/mybatis-plus-spring-boot-native-image/src/main/java/com/baomidou/mybatisplus/aot/MyBatisPlusNativeImageConfiguration.java:97

    @Bean
    static MyBatisMapperFactoryBeanPostProcessor myBatisMapperFactoryBeanPostProcessor() {
        return new MyBatisMapperFactoryBeanPostProcessor();
    }

    static class MyBatisRuntimeHintsRegistrar implements RuntimeHintsRegistrar {

        @Override
        public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
            AotUtils aotUtils = new AotUtils(hints, classLoader);
            registerXml(aotUtils);
        }

        private void registerXml(AotUtils aotUtils) {
            try {
                aotUtils.registerPattern(aotUtils.findResources("",
                    CollectUtils::isMapperXmlResource).toArray(AotUtils.EMPTY_STRING_ARRAY));
            } catch (IOException e) {
                throw new RuntimeException("注册用户目录的xml文件失败", e);
            }
        }

    }

    static class MyBatisBeanFactoryInitializationAotProcessor
        implements BeanFactoryInitializationAotProcessor, BeanRegistrationExcludeFilter {

        private final Set<Class<?>> excludeClasses = new HashSet<>();

        MyBatisBeanFactoryInitializationAotProcessor() {
            excludeClasses.add(MapperScannerConfigurer.class);
        }

        @Override
        public boolean isExcludedFromAotProcessing(RegisteredBean registeredBean) {
            return excludeClasses.contains(registeredBean.getBeanClass());
        }

View on GitHub (pinned to bf67d90747)

Solutions

  1. Inspect the cause IOException to identify the unreadable classpath entry and fix packaging/permissions
  2. Keep mapper XMLs in plain resource directories of the application jar rather than nested/shaded jars
  3. Fall back to explicit GraalVM resource configuration (META-INF/native-image/.../resource-config.json listing mapper/**/*.xml)
  4. Match the Spring Boot / GraalVM plugin versions certified with this starter version
Defensive patterns

Strategy: try-catch

Validate before calling

// Sanity-check classloader resource enumeration before AOT processing
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Enumeration<URL> urls = cl.getResources("");
while (urls.hasMoreElements()) {
    URL u = urls.nextElement();
    try { new java.io.File(u.toURI()).canRead(); }
    catch (Exception ex) { throw new IllegalStateException("Unreadable classpath entry: " + u, ex); }
}

Try / catch

try {
    // native-image build with auto-configuration active
} catch (RuntimeException e) {
    if ("注册用户目录的xml文件失败".equals(e.getMessage())) {
        throw new IllegalStateException("Native-image AOT mapper XML scan failed", e.getCause());
    }
    throw e;
}

Prevention

When it happens

Trigger: Building a native image with mybatis-plus-spring-boot-native-image auto-configuration active; during AOT processing the classpath scan for resources matching CollectUtils.isMapperXmlResource throws IOException (unreadable nested jars, unusual protocols, filesystem errors).

Common situations: Native-image builds in CI with restrictive file permissions; Spring Boot versions whose LaunchedURLClassLoader resource enumeration behaves differently; multi-module builds packaging mapper XMLs in shaded or nested jars.

Related errors


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