flowable/flowable-engine · error · FlowableClassLoadingException
Could not load class: ${className} (or 'Class not found: ${c
Error message
Could not load class: ${className} (or 'Class not found: ${className}' when cause is ClassNotFoundException) What it means
ReflectUtil.loadClass tries the context classloader, the current class's classloader, and other fallbacks to load a class by name; if all attempts fail it throws FlowableClassLoadingException with the message 'Could not load class: X' (or 'Class not found: X' when the root cause is a ClassNotFoundException). The real cause (LinkageError, security issue, etc.) is attached.
Source
Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/util/ReflectUtil.java:89
} catch (Throwable t) {
if (throwable == null) {
throwable = t;
}
}
if (clazz == null) {
try {
LOGGER.trace("Trying to load class with local classloader: {}", className);
clazz = loadClass(ReflectUtil.class.getClassLoader(), className);
} catch (Throwable t) {
if (throwable == null) {
throwable = t;
}
}
}
}
if (clazz == null) {
throw new FlowableClassLoadingException(className, throwable);
}
return clazz;
}
public static boolean isClassPresent(String className) {
try {
loadClass(className);
return true;
} catch (FlowableClassLoadingException ignored) {
return false;
}
}
public static InputStream getResourceAsStream(String name) {
InputStream resourceStream = null;
ClassLoader classLoader = getCustomClassLoader();
if (classLoader != null) {
resourceStream = classLoader.getResourceAsStream(name);View on GitHub (pinned to d6d39ce1c6)
Solutions
- Verify the fully-qualified class name in your configuration is spelled correctly and case-exact.
- Confirm the class is on the runtime classpath (check the packaged jar/war, mvn dependency:tree).
- Inspect the 'cause' of FlowableClassLoadingException: ClassNotFoundException means missing; NoClassDefFoundError/LinkageError means dependency version conflict.
- Add the missing dependency or fix its scope (compile instead of provided/test).
- If using OSGi or custom classloaders, ensure ReflectUtil can find the class via the thread context classloader.
Example fix
// before <flowable:class delegateExpression="com.acme.MyDelegate"/> <!-- wrong name --> // after <!-- exact FQN of a class present on the runtime classpath --> <flowable:class delegateExpression="com.acme.order.MyJavaDelegate"/>
Defensive patterns
Strategy: try-catch
Validate before calling
if (!ReflectUtil.isClassPresent(className)) {
throw new IllegalStateException("Class not on classpath: " + className);
} Try / catch
try {
Class<?> c = ReflectUtil.loadClass(className);
} catch (FlowableClassLoadingException e) {
LOGGER.error("Cannot load {}: {}", className, e.getCause(), e);
throw newConfigurationException(className, e.getCause());
} Prevention
- Keep fully-qualified class names in config in sync with refactors
- Check dependency scopes so runtime-needed classes are packaged
- Inspect e.getCause(): ClassNotFoundException vs NoClassDefFoundError indicate different fixes
- Run smoke tests in the packaged artifact, not just the IDE
When it happens
Trigger: Calling ReflectUtil.loadClass(className) or isClassPresent-dependent code paths with a class name that is misspelled, not on the classpath, or whose static initializer/linking fails.
Common situations: Configuring custom classes (delegates, listeners, serializers) in process XML or config with wrong fully-qualified names; dependencies missing at runtime in fat jars/containers; class exists in a provided-scope dependency not packaged; Java version mismatch breaking linking.
Related errors
- database update java class '${upgradestepClassName}' can't b
- BPMN XSD could not be found
- CMND XSD could not be found
- resource '${resource}' not found
- Class ${className} not found
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/968a3fc65f896354.
Report an issue: GitHub.