flowable/flowable-engine · error · ELException
Class or class name is missing
Error message
Class or class name is missing
What it means
javax.el.ELException thrown by JuelScriptEngine.importFunctions when the value registered for a function importer is neither a Class, an object instance, nor a String class name loadable by ReflectUtil.loadClass. The engine needs a class to enumerate its static public methods as EL functions.
Solutions
- Pass either a java.lang.Class object, an object instance whose class is used, or a fully qualified class name String to importFunctions.
- Verify the class name String is on the classpath so ReflectUtil.loadClass succeeds (a failed load raises ELException wrapping FlowableException).
- Log the actual type of the imported value before registration to catch wrong objects early.
Example fix
// before engine.importFunctions(scope, "fn", Arrays.asList(Math.class)); // after engine.importFunctions(scope, "fn", Math.class);
Defensive patterns
Strategy: type-guard
Validate before calling
if (!(obj instanceof Class) && !(obj instanceof String) && obj == null) {
throw new IllegalArgumentException("importFunctions expects a Class or class-name String");
} Type guard
boolean isImportable(Object o) {
return o instanceof Class || o instanceof String;
} Try / catch
try {
engine.importFunctions(scope, ns, obj);
} catch (ELException e) {
log.error("failed to import functions from {}: {}", obj, e.getMessage());
} Prevention
- Only pass Class objects or FQCN strings to importFunctions
- Verify class is on the classpath with ReflectUtil.loadClass in tests
- Log the runtime type of configured function importer objects
When it happens
Trigger: Calling juelScriptEngine.importFunctions(scope, namespace, obj) where obj is an unexpected type (e.g. a primitive wrapper, a List of classes, or an arbitrary object that is not a Class and not a class-name String).
Common situations: Custom script engine configuration passing a misconfigured bean into the function importer; loading classes from a script where the class reference resolved to something other than a Class/String; typos or refactors in custom scripting setup.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Error evaluating juel script
- Method getMethodCallSyntax is not supported
- Class or class name is missing
- condition script returns non-Boolean: () for
- condition script returns null: for
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/31865e6fadd0fe2f.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/scripting/JuelScriptEngine.java:232
return JuelScriptEngine.class.getMethod("importFunctions", new Class[] { ScriptContext.class, String.class, Object.class });
} catch (Exception exp) {
// Will never occur
return null;
}
}
public static void importFunctions(ScriptContext ctx, String namespace, Object obj) {
Class<?> clazz = null;
if (obj instanceof Class) {
clazz = (Class<?>) obj;
} else if (obj instanceof String) {
try {
clazz = ReflectUtil.loadClass((String) obj);
} catch (FlowableException ae) {
throw new ELException(ae);
}
} else {
throw new ELException("Class or class name is missing");
}
Method[] methods = clazz.getMethods();
for (Method m : methods) {
int mod = m.getModifiers();
if (Modifier.isStatic(mod) && Modifier.isPublic(mod)) {
String name = namespace + ":" + m.getName();
ctx.setAttribute(name, m, ScriptContext.ENGINE_SCOPE);
}
}
}
/**
* Class representing a compiled script using JUEL.
*
* @author Frederik Heremans
*/
private class JuelCompiledScript extends CompiledScript {
View on GitHub (pinned to d6d39ce1c6)