flowable/flowable-engine · error · IllegalStateException
Invalid ScriptEngineFactory:
Error message
Invalid ScriptEngineFactory:
What it means
Extender.resolveScriptEngine loads the class named in a script engine factory descriptor inside an OSGi bundle and validates that it implements javax.script.ScriptEngineFactory. If the loaded class does not implement that interface, it throws IllegalStateException('Invalid ScriptEngineFactory: <class name>'). This protects the subsequent cast and instantiation from a ClassCastException.
Source
Thrown at modules/flowable-osgi/src/main/java/org/flowable/osgi/Extender.java:381
if (reg != null) {
reg.unregister();
}
}
@SuppressWarnings({"rawtypes"})
@Override
public ScriptEngine resolveScriptEngine(String name) {
try {
String className;
try (InputStream input = configFile.openStream()) {
className = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8)).lines()
.map(line -> line.split("#", 2)[0].trim())
.filter(Predicate.not(String::isBlank))
.findFirst().orElse(null);
}
Class<?> cls = bundle.loadClass(className);
if (!ScriptEngineFactory.class.isAssignableFrom(cls)) {
throw new IllegalStateException("Invalid ScriptEngineFactory: " + cls.getName());
}
ScriptEngineFactory factory = (ScriptEngineFactory) cls.getConstructor().newInstance();
List<String> names = factory.getNames();
for (String test : names) {
if (test.equals(name)) {
ClassLoader old = Thread.currentThread().getContextClassLoader();
ScriptEngine engine;
try {
// JRuby seems to require the correct TCCL to call
// getScriptEngine
Thread.currentThread().setContextClassLoader(factory.getClass().getClassLoader());
engine = factory.getScriptEngine();
} finally {
Thread.currentThread().setContextClassLoader(old);
}
LOGGER.trace("Resolved ScriptEngineFactory: {} for expected name: {}", engine, name);
return engine;
}View on GitHub (pinned to d6d39ce1c6)
Solutions
- Correct the factory class name in the script engine descriptor to a class implementing ScriptEngineFactory
- Verify the bundle exporting the script engine factory is deployed and its class is public with a no-arg constructor
- Check for version mismatches between the script engine library and the descriptor file
- Rebuild/redeploy the bundle if the class was recently renamed
Example fix
// before (descriptor content) com.example.MyEngineImpl // does not implement ScriptEngineFactory // after com.example.MyEngineFactory // implements javax.script.ScriptEngineFactory
Defensive patterns
Strategy: validation
Validate before calling
Class<?> cls = bundle.loadClass(factoryClassName);
if (!javax.script.ScriptEngineFactory.class.isAssignableFrom(cls)) {
throw new IllegalArgumentException(factoryClassName + " does not implement ScriptEngineFactory");
} Try / catch
try {
ScriptEngine engine = scriptEngine.getEngineByName(language);
} catch (FlowableException e) {
if (e.getMessage().startsWith("problem resolving scripting engine")) {
logger.error("Script engine resolution failed for {}: {}", language, e.getCause().getMessage());
}
throw e;
} Prevention
- Keep engine factory descriptor files in sync with actual class names after refactors
- Test each registered script engine factory instantiates at bundle start
- Pin script engine library versions and regenerate descriptors on upgrades
When it happens
Trigger: A bundle's script-engine registration file (e.g. META-INF/services or the OSGi launcher config) lists a className that resolves via bundle.loadClass to a class that is not a ScriptEngineFactory, during resolveScriptEngine (called from resolvedEngine).
Common situations: Typo'd or wrong class name in the engine factory descriptor; a class was renamed/refactored across Flowable or script engine versions; wrong bundle's classloader resolving an unrelated class with the same name.
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
- problem resolving scripting engine:
- from bundle
- Cannot create ScriptEngineFactory: {}
- 'language' evaluated to null for taskListener of type 'scrip
- Script content is null or evaluated to null for taskListener
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/0e08cb2ef19320ce.
Report an issue: GitHub.