flowable/flowable-engine · error · ELException
Class ${className} could not be instantiated
Error message
Class ${className} could not be instantiated What it means
Thrown by the EL implementation's class-loading helper (ExpressionFactoryImpl.load) when the class for a given className was found and loaded but could not be instantiated (any exception other than ClassNotFoundException). The library wraps the underlying reflective instantiation failure (e.g. missing public no-arg constructor, constructor threw, or illegal access) in an ELException with this message.
Source
Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/ExpressionFactoryImpl.java:429
return new Builder(features);
}
private Class<?> load(Class<?> clazz, Properties properties) {
if (properties != null) {
String className = properties.getProperty(clazz.getName());
if (className != null) {
ClassLoader loader;
try {
loader = Thread.currentThread().getContextClassLoader();
} catch (Exception e) {
throw new ELException("Could not get context class loader", e);
}
try {
return loader == null ? Class.forName(className) : loader.loadClass(className);
} catch (ClassNotFoundException e) {
throw new ELException("Class " + className + " not found", e);
} catch (Exception e) {
throw new ELException("Class " + className + " could not be instantiated", e);
}
}
}
return null;
}
@Override
public final <T> T coerceToType(Object obj, Class<T> targetType) {
return converter.convert(obj, targetType);
}
@Override
public final ObjectValueExpression createValueExpression(Object instance, Class<?> expectedType) {
return new ObjectValueExpression(converter, instance, expectedType);
}
@Override
public final TreeValueExpression createValueExpression(ELContext context, String expression, Class<?> expectedType) {View on GitHub (pinned to d6d39ce1c6)
Solutions
- Check the cause chained in the ELException: it names the exact instantiation problem (NoSuchMethodException, InstantiationException, InvocationTargetException).
- Ensure the referenced class is public, concrete (not abstract/interface), and has a public no-arg constructor.
- Fix any static initializer or constructor code that throws in the deployment environment (missing config, dependencies).
- Verify the class name string in the expression/config matches an existing class on the classpath for the current library version.
Example fix
// before: expression references abstract type foo = com.example.AbstractHandler // after: reference a concrete, no-arg-constructible class foo = com.example.DefaultHandler
Defensive patterns
Strategy: try-catch
Validate before calling
Class<?> c = Class.forName(className); if (c.isInterface() || Modifier.isAbstract(c.getModifiers())) throw new IllegalArgumentException(className + " is not instantiable"); c.getDeclaredConstructor(); // fails fast if no no-arg constructor
Type guard
boolean isInstantiable(Class<?> c) {
return c != null && !c.isInterface() && !Modifier.isAbstract(c.getModifiers())
&& java.util.Arrays.stream(c.getConstructors()).anyMatch(k -> k.getParameterCount() == 0 && Modifier.isPublic(k.getModifiers()));
} Try / catch
try {
Object o = expression.eval(context);
} catch (ELException e) {
Throwable cause = e.getCause();
log.error("Class instantiation failed: {}", cause != null ? cause.toString() : e.getMessage(), e);
} Prevention
- Only reference public concrete classes with public no-arg constructors in EL expressions.
- Check e.getCause() of ELException for the exact reflective failure.
- Keep class names in configuration in sync with refactors between library versions.
- Avoid static-initializer code that can throw in restricted environments.
When it happens
Trigger: An EL expression or type reference causes load(className) to be invoked; Class.forName/loadClass succeeds but instantiating the class fails because the class has no accessible no-arg constructor, its constructor throws, or it is abstract/interface.
Common situations: Custom FunctionMapper/ELResolver entries or expression operands naming a class whose implementation changed between versions; referencing an abstract class or interface in an expression; a class with initialization code that fails at static-init time in the target environment.
Related errors
- TypeConverter ${clazz} could not be instantiated
- Builder ${clazz} is missing constructor (can't pass features
- TreeBuilder ${clazz} could not be instantiated
- Could not get context class loader
- Class ${className} not found
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/201f603aaf771c35.
Report an issue: GitHub.