Expression Factory

To start using the EL, you need an instance of javax.el.ExpressionFactory. The expression factory is used to create expressions of various types.

JUEL's expression factory implementation is de.odysseus.el.ExpressionFactoryImpl. The easiest way to obtain an expression factory instance is

javax.el.ExpressionFactory factory = new de.odysseus.el.ExpressionFactoryImpl();

An expression factory is thread-safe and can create an unlimited number of expressions. The expression factory provides operations to

Expression Cache

Each factory instance uses its own expression cache. Caching expressions can be an important issue, because parsing is relative expensive. An expression cache maps expression strings to their parsed representations (trees).

JUEL provides a caching interface which allows applications to use their own caching mechanism. However, in most scenarios, JUEL's default implementation (based on java.util.concurrent.ConcurrentHashMap and java.util.concurrent.ConcurrentLinkedQueue) should be fine.

The caching mechanism has been rewritten for JUEL 2.2.5 to improve performance.

The default constructor uses a maximum cache size of 1000. You may specify a different value - say 5000 - by specifying the javax.el.cacheSize property.

java.util.Properties properties = new java.util.Properties();
properties.put("javax.el.cacheSize", "5000");
javax.el.ExpressionFactory factory = new de.odysseus.el.ExpressionFactoryImpl(properties);

Using your own caching mechanism is covered in the Advanced Topics secion.

Type Conversions

Type conversions are performed at several points while evaluating expressions.

  • Operands are coerced when performing arithmetic or logical operations
  • Value expression results are coerced to the expected type specified at creation time
  • For literal method expressions the text is coerced to the type specified at creation time
  • For non-literal method expressions the last property is coerced to a method name
  • Composite expression coerce their sub-expressions to strings before concatenating them

All these coercions are done following the same rules. The specification describes these coercion rules in detail. It supports converting between string, character, boolean, enumeration and number types. Additionally, the conversion of strings to other types is supported by the use of (Java Beans) property editors. The EL makes the coercion rules available to client applications via the expression factory method

ExpressionFactoryImpl.coerceToType(Object, Class<?>)

whose return type is Object.

JUEL can be configured to use alternative coercion rules as described in the Advanced Topics secion.

Factory Configuration

The factory may be configured via property files. The mechanism described here is used when an expression factory is created without specifying properties. The lookup procedure for properties is as follows:

  1. JAVA_HOME/lib/ - If this file contains property javax.el.ExpressionFactory whose value is de.odysseus.el.ExpressionFactoryImpl, its properties are loaded and taken as default properties.
  2. System.getProperties() - if the previous rule (1) did not match and system property javax.el.ExpressionFactory is set to de.odysseus.el.ExpressionFactoryImpl, the system properties are taken as default properties.
  3. anywhere on your classpath - These properties may override the default properties from (1) or (2).

Having this, the following properties are read:

  • javax.el.cacheSize - expression cache size (default is 1000)
  • javax.el.methodInvocations - set to true to allow method invocations. Please refer to the Advanced Topics section for more on this.
  • javax.el.nullProperties - set to true to resolve null properties. Please refer to the Advanced Topics section for more on this.
  • javax.el.varArgs - set to true to allow vararg function/method calls in your expressions.

The factory class also provides constructors which let you explicitly pass your properties. If you just want to switch between JEE5 and JEE6 style, JUEL provides enum constants to use as profiles.