flowable/flowable-engine · warning · ELException
Could not get context class loader
Error message
Could not get context class loader
What it means
load() resolves a class named in the factory properties and tries to use the thread context class loader (TCCL) to load it. If obtaining the TCCL itself throws (rare: security manager or unusual threading environment), it wraps the exception in ELException 'Could not get context class loader'.
Source
Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/ExpressionFactoryImpl.java:422
}
} catch (Exception e) {
throw new ELException("TreeBuilder " + clazz + " could not be instantiated", e);
}
}
protected TreeBuilder createDefaultTreeBuilder(Feature... features) {
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);
}
View on GitHub (pinned to d6d39ce1c6)
Solutions
- Grant RuntimePermission("getClassLoader") to the application's security policy
- Remove or relax the SecurityManager restrictions for the engine's execution context
- Set the factory classes explicitly so they resolve without context-loader lookup, or run with a standard thread context
Example fix
// before (java.policy)
grant { };
// after
grant {
permission java.lang.RuntimePermission "getClassLoader";
}; Defensive patterns
Strategy: try-catch
Validate before calling
try {
ClassLoader l = Thread.currentThread().getContextClassLoader();
} catch (SecurityException e) {
throw new IllegalStateException("Security policy denies getClassLoader; grant RuntimePermission before engine init");
} Try / catch
try {
ExpressionFactory factory = new ExpressionFactoryImpl();
} catch (ELException e) {
if (e.getMessage().contains("Could not get context class loader")) {
throw new IllegalStateException("Review SecurityManager policy: getClassLoader permission required", e);
}
throw e;
} Prevention
- Audit java.policy grants when running with a SecurityManager
- Test engine startup under the target container's security configuration
- Avoid exotic Thread subclasses that override getContextClassLoader
When it happens
Trigger: ExpressionFactoryImpl.load() (accessed via the clazz() accessor while resolving property-configured classes) calls Thread.currentThread().getContextClassLoader() and the call throws — typically under a restrictive Java SecurityManager or a container that denies RuntimePermission 'getClassLoader'.
Common situations: Running inside an application server or sandbox with a SecurityManager that blocks context classloader access; exotic custom thread implementations whose getContextClassLoader throws.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- TypeConverter ${clazz} could not be instantiated
- Builder ${clazz} is missing constructor (can't pass features
- TreeBuilder ${clazz} could not be instantiated
- Class ${className} not found
- Class ${className} could not be instantiated
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/2568b450b2d22536.
Report an issue: GitHub.