{"record":{"id":"40c1d5eef379f1da","repo":"flowable/flowable-engine","slug":"failed-to-read-mappings","errorCode":null,"errorMessage":"Failed to read mappings ","messagePattern":"Failed to read mappings ","errorType":"exception","errorClass":"UncheckedIOException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/aot/FlowableMyBatisResourceHintsRegistrar.java","lineNumber":52,"sourceCode":" *\n * @author Filip Hrisafov\n */\npublic class FlowableMyBatisResourceHintsRegistrar {\n\n    public static void registerMappingResources(String baseFolder, RuntimeHints runtimeHints, ClassLoader classLoader) {\n        ResourceHints resourceHints = runtimeHints.resources();\n        String mappingsPath = baseFolder + \"/mappings.xml\";\n        ClassPathResource mappingsResource = new ClassPathResource(mappingsPath);\n        resourceHints.registerResource(mappingsResource);\n        try (InputStream mappingsStream = mappingsResource.getInputStream()) {\n            XPathParser parser = createParser(mappingsStream);\n\n            List<XNode> mappers = parser.evalNodes(\"/configuration/mappers/mapper\");\n            for (XNode mapper : mappers) {\n                registerMapper(mapper.getStringAttribute(\"resource\"), runtimeHints, classLoader);\n            }\n        } catch (IOException e) {\n            throw new UncheckedIOException(\"Failed to read mappings \" + mappingsPath, e);\n        }\n    }\n\n    public static void registerMapper(String mapperPath, RuntimeHints hints, ClassLoader classLoader) {\n        ResourceHints resourceHints = hints.resources();\n        ClassPathResource mapperResource = new ClassPathResource(mapperPath);\n        resourceHints.registerResource(mapperResource);\n\n        ReflectionHints reflectionHints = hints.reflection();\n        MemberCategory[] memberCategories = MemberCategory.values();\n        try (InputStream mapperStream = mapperResource.getInputStream()) {\n            XPathParser parser = createParser(mapperStream);\n            XNode mapper = parser.evalNode(\"/mapper\");\n            // The xpath resolving is similar like what MyBatis does in XMLMapperBuilder#parse\n            for (XNode resultMap : mapper.evalNodes(\"/mapper/resultMap\")) {\n                String type = resultMap.getStringAttribute(\"type\");\n                if (type != null) {\n                    reflectionHints.registerType(TypeReference.of(type), memberCategories);","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/aot/FlowableMyBatisResourceHintsRegistrar.java#L34-L70","documentation":"Thrown (as UncheckedIOException) by FlowableMyBatisResourceHintsRegistrar.registerMappingResources when the MyBatis configuration file referenced by mappingsPath cannot be read while registering AOT/native-image reflection and resource hints. IOException from classpath loading or stream opening is wrapped with the failing path in the message.","triggerScenarios":"Spring native/GraalVM AOT processing with a mappings path that is missing from the classpath, unreadable, or malformed so parsing fails with an IOException.","commonSituations":"Wrong mybatis mappings config property (typo in resource path); resource not packaged in a fat jar or native image; resources filtering stripping the XML; running with a stripped classpath in AOT build.","solutions":["Verify the mappings path configured for the engine exists on the classpath (org/flowable/db/mapping/...xml) and is spelled correctly.","Ensure the XML files are included in the build artifact (check Maven resource filtering / Gradle processResources excludes).","Register the MyBatis XML resources as native-image resources (resources.includes) so AOT can read them.","Check that the file is valid XML and openable via the configured ClassLoader (test classLoader.getResourceAsStream(mappingsPath))."],"exampleFix":"// before\n<resource><directory>src/main/resources</directory><excludes><exclude>**/*.xml</exclude></excludes></resource>\n// after\n<resource><directory>src/main/resources</directory><includes><include>**/*.xml</include></includes></resource>","handlingStrategy":"validation","validationCode":"try (InputStream in = classLoader.getResourceAsStream(mappingsPath)) {\n  if (in == null) throw new IllegalStateException(\"MyBatis config not on classpath: \" + mappingsPath);\n}","typeGuard":null,"tryCatchPattern":"try {\n  registrar.registerHints(runtimeHints, classLoader);\n} catch (UncheckedIOException e) {\n  if (e.getMessage().startsWith(\"Failed to read mappings\")) {\n    log.error(\"MyBatis mappings missing/unreadable at AOT time: {}\", mappingsPath, e);\n  }\n  throw e;\n}","preventionTips":["Verify the mappings config path exists on the classpath before starting AOT builds.","Keep XML resources out of Maven filtering/exclusion rules.","Register MyBatis XMLs as native-image resources in RuntimeHints.","Test native-image builds in CI to catch missing resources early."],"tags":["mybatis","aot","resource","io"],"backgroundTag":"file-read-failed","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}