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

  1. Pass either a java.lang.Class object, an object instance whose class is used, or a fully qualified class name String to importFunctions.
  2. Verify the class name String is on the classpath so ReflectUtil.loadClass succeeds (a failed load raises ELException wrapping FlowableException).
  3. 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

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


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)