flowable/flowable-engine · error · ELException
Cannot read EL properties
Error message
Cannot read EL properties
What it means
loadProperties() loads a user-supplied EL properties file (given by path) from the classpath or filesystem. If the stream is found but properties.load() throws an IOException, it wraps it as ELException 'Cannot read EL properties'. Unlike the default-properties variant, the resource here is application-provided.
Source
Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/ExpressionFactoryImpl.java:299
}
return null;
}
private Properties loadProperties(String path) {
Properties properties = new Properties(loadDefaultProperties());
// try to find and load properties
InputStream input = null;
try {
input = Thread.currentThread().getContextClassLoader().getResourceAsStream(path);
} catch (SecurityException e) {
input = ClassLoader.getSystemResourceAsStream(path);
}
if (input != null) {
try {
properties.load(input);
} catch (IOException e) {
throw new ELException("Cannot read EL properties", e);
} finally {
try {
input.close();
} catch (IOException e) {
// ignore...
}
}
}
return properties;
}
private boolean getFeatureProperty(Profile profile, Properties properties, Feature feature, String property) {
return Boolean.valueOf(properties.getProperty(property, String.valueOf(profile.contains(feature))));
}
/**
* Create the factory's tree store. This implementation creates a new tree store using theView on GitHub (pinned to d6d39ce1c6)
Solutions
- Fix the syntax of the custom properties file — escape special characters and use latin-1/\uXXXX escapes
- Validate the file loads standalone with new Properties().load(new FileInputStream(file)) before deploying
- Re-copy the resource into the classpath (verify it is not truncated)
Example fix
// before (broken el.properties) cacheSize=1024 builder=de.odysseus.el.tree.impl ??? // after de.odysseus.el.tree.impl.TreeStore.cacheSize = 1024
Defensive patterns
Strategy: validation
Validate before calling
// Validate a custom EL properties file before pointing the factory at it
Properties p = new Properties();
try (InputStream in = new FileInputStream("el.properties")) {
p.load(in); // will throw IOException on malformed content
} Try / catch
try {
ExpressionFactory factory = new ExpressionFactoryImpl(props);
} catch (ELException e) {
if (e.getCause() instanceof IOException) {
log.error("Custom EL properties file unreadable/malformed", e);
}
throw e;
} Prevention
- Escape non-latin1 characters as \uXXXX in properties files
- Load-test properties files in CI before shipping
- Never hand-edit deployed files; regenerate via build
When it happens
Trigger: Creating an ExpressionFactoryImpl (or ExpressionFactory.newInstance) with a Properties entry pointing to a custom EL properties file whose contents cannot be parsed as a java.util.Properties stream — malformed input, wrong encoding, or stream that fails mid-read.
Common situations: Hand-edited juel.properties / EL properties file with invalid syntax or binary garbage; file on classpath with wrong encoding (not ISO-8859-1/escape format); truncated resource copied into the WAR.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- Cannot read default EL properties
- Cannot parse EL property ${PROP_CACHE_SIZE}
- TypeConverter ${clazz} could not be instantiated
- Builder ${clazz} is missing constructor (can't pass features
- TreeBuilder ${clazz} could not be instantiated
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/bcb4c55dea5c14e3.
Report an issue: GitHub.