flowable/flowable-engine · critical · IllegalArgumentException
Class ${customMybatisMapperClassName} has not been found.
Error message
Class ${customMybatisMapperClassName} has not been found. What it means
During Flowable engine auto-configuration (Spring Boot), getCustomMybatisMapperClasses loads each class named in the customMyBatisMappers property via Class.forName and throws IllegalArgumentException when the class cannot be found on the classpath. MyBatis mapper interfaces must be present as classes for the engine to register them, so a misspelled or missing mapper class aborts engine startup. The ClassNotFoundException is chained as the cause.
Source
Thrown at modules/flowable-spring-boot/flowable-spring-boot-starters/flowable-spring-boot-autoconfigure/src/main/java/org/flowable/spring/boot/AbstractEngineAutoConfiguration.java:121
}
if (result.isEmpty()) {
logger.info("No deployment resources were found for autodeployment");
}
return result;
}
return new ArrayList<>();
}
protected Set<Class<?>> getCustomMybatisMapperClasses(List<String> customMyBatisMappers) {
Set<Class<?>> mybatisMappers = new HashSet<>();
for (String customMybatisMapperClassName : customMyBatisMappers) {
try {
Class customMybatisClass = Class.forName(customMybatisMapperClassName);
mybatisMappers.add(customMybatisClass);
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException("Class " + customMybatisMapperClassName + " has not been found.", e);
}
}
return mybatisMappers;
}
protected String defaultText(String deploymentName, String defaultName) {
if (StringUtils.hasText(deploymentName)) {
return deploymentName;
}
return defaultName;
}
}
View on GitHub (pinned to d6d39ce1c6)
Solutions
- Correct the fully-qualified class name in the custom-mybatis-mappers property (check spelling/package).
- Add the jar/module containing the mapper interface to the application classpath.
- Verify the class exists with Class.forName or an IDE 'go to class' before configuring it.
- If the mapper became unnecessary after an upgrade, remove its entry from the property.
Example fix
// before (application.yml) flowable: custom-mybatis-mappers: com.example.mappers.TaskExstensionMapper // after (typo fixed) flowable: custom-mybatis-mappers: com.example.mappers.TaskExtensionMapper
Defensive patterns
Strategy: validation
Validate before calling
// Fail fast at startup, before Spring context builds the engine
for (String name : props.getCustomMybatisMappers()) {
try {
Class.forName(name);
} catch (ClassNotFoundException e) {
throw new IllegalStateException("Mapper class not on classpath: " + name, e);
}
} Prevention
- Copy fully-qualified mapper names from the IDE (FQN) rather than typing them.
- Ensure the module/jar containing the mapper interface is a runtime dependency.
- After refactors or Flowable upgrades, re-run startup smoke tests that build the engine.
- Keep custom mapper classes in a stable package to avoid rename breakage.
When it happens
Trigger: Spring Boot app startup with flowable.*.custom-mybatis-mappers containing a class name that is not on the application classpath (typo, wrong package, missing dependency, renamed class, missing module jar).
Common situations: Fully-qualified name typo in application.yml/properties; custom mapper interface defined in a module not included in the deployment; class renamed after a refactor or Flowable version upgrade; configuring mappers for an engine (e.g. cmmn) whose module isn't on the classpath.
Related errors
- Failed to load type alias class
- Failed to load type handler class
- Could not read IDM Mybatis configuration file
- resource '${resource}' not found
- Failed to read resource ${resource}
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/b981f5b66aa7dc72.
Report an issue: GitHub.