Apache Commons JEXL Overview ? Apache Commons JEXL
Apache Commons JEXL ™
Last Published: 05 Feb 2026
Version: 3.6.2
ApacheCon
Apache
Commons
Commons JEXL
About
Asking Questions
Release History
Issue Tracking
Dependency Management
Sources
Security
License
Code of Conduct
Javadoc
Javadoc Current
Javadoc Archive
Javadoc Last 2.x (2.1.1)
Javadoc Last 1.x (1.1)
Release Notes
Reference
Project Documentation
Project Information
About
Summary
Team
Source Code Management
Issue Management
Mailing Lists
Maven Coordinates
Dependency Management
Dependencies
Dependency Convergence
CI Management
Distribution Management
Project Reports
Commons
License
Components
Sandbox
Dormant
General Information
Security
Volunteering
Contributing Patches
Building Components
Commons Parent POM
Commons Build Plugin
Commons Release Plugin
Site Publication
Releasing Components
Wiki
ASF
How the ASF works
Get Involved
Developer Resources
Code of Conduct
Sponsorship
Thanks
Java Expression Language (JEXL)
JEXL is a library intended to facilitate the implementation of dynamic and scripting features in
applications and frameworks written in Java.
JEXL implements an Expression Language based on some extensions to the JSTL Expression Language supporting most of the
constructs seen in shell-script or ECMAScript.
Its goal is to expose scripting features usable by technical operatives or consultants
working with enterprise platforms.
In many use cases, JEXL allows end-users of an application to code their own scripts or expressions
and ensure their execution within controlled functional constraints.
The library exposes a small footprint API
- the
core features
fit in
3 classes and 10 methods - that can be used in various conditions:
Scripting features:
Your application lets (advanced) users evaluate or define some simple expressions
like computation formulas.
Module or component configuration:
Your application has configuration files (eventually generated by a design module)
consumed by the end-user module that would benefit from variables and expressions.
When it would be convenient to use IOC but overall complexity doesn't require
(or can't depend upon) a full-blown library (Spring, Guice...).
Loose-coupling of interfaces and implementations or duck-typing:
You have optional classes that your code cant consider as compilation dependencies.
You have to integrate and call "legacy" code or use components that you don't want to
strongly depend upon.
Simple template capabilities:
Your application has basic template requirements and JSPs or
Velocity would be overkill or too inconvenient to deploy.
JEXL name stands for Java EXpression Language, a simple expression language originally inspired by Apache
Velocity and the Expression Language defined in the JavaServer Pages Standard Tag Library version 1.1 (JSTL)
and JavaServer Pages version 2.0 (JSP).
JEXL 2.0 added features inspired by
Unified EL
The syntax is now close to a mix of ECMAScript and "shell-script"
making it easy to master by technical operatives or consultants. The objects exposed and their behavior
obviously need to be documented though...
The API and the expression language exploit Java-beans naming patterns through
introspection to expose property getters and setters. It also considers public class fields
as properties and allows to invoke any accessible method.
A Detailed Example
To create expressions and scripts, a
JexlEngine
is required.
To instantiate one, a
JexlBuilder
is needed to describe the allowed
JexlPermissions
and
JexlFeatures
that will determine
which classes and methods scripts can access and call and which syntactic elements
scripts are allowed to use. Do not overlook this configuration aspect,
especially the permissions since
security of your application
might depend on it.
Once built, the JEXL engine should be stored, shared and reused.
It is thread-safe ; so are the scripts during evaluation.
When evaluating expressions, JEXL merges an
JexlExpression
or a
JexlScript
with a
JexlContext
In its simplest form, a script is created using
JexlEngine#createExpression()
passing a String containing valid JEXL syntax. A simple JexlContext can be created by instantiating a
MapContext
a map of variables that will be internally wrapped can be optionally provided through its constructor.
JEXL's intention is a tight integration with its hosting platform; the scripting syntax is very close
to JScript but leverages (potentially) any public class or method that Java exposes. How tight and how
rich this integration is up to you; deriving JEXL API classes - most notably JexlPermissions, JexlContext,
JexlArithmetic - are the means to that end.
The following example illustrate these aspects. It uses a specific set of permissions to allow using
URI class and a tailored context to expose streams in a convenient manner.
/**
* A test around scripting streams.
*/
public
class
StreamTest
/** Our engine instance. */
private
final
JexlEngine jexl;
public
StreamTest()
// Restricting features; no loops, no side effects
JexlFeatures features =
new
JexlFeatures()
.loops(
false
.sideEffectGlobal(
false
.sideEffect(
false
);
// Restricted permissions to a safe set but with URI allowed
JexlPermissions permissions =
new
ClassPermissions(java.net.URI.class);
// Create the engine
jexl =
new
JexlBuilder().features(features).permissions(permissions).create();
/**
* A MapContext that can operate on streams.
*/
public
static
class
StreamContext
extends
MapContext
/**
* This allows using a JEXL lambda as a mapper.
* @param stream the stream
* @param mapper the lambda to use as mapper
* @return the mapped stream
*/
public
Stream map(Stream stream,
final
JexlScript mapper)
return
stream.map( x -> mapper.execute(this, x));
/**
* This allows using a JEXL lambda as a filter.
* @param stream the stream
* @param filter the lambda to use as filter
* @return the filtered stream
*/
public
Stream filter(Stream stream,
final
JexlScript filter)
return
stream.filter(x -> x =!
null
&& TRUE.equals(filter.execute(this, x)));
@Test
public
void
testURIStream()
throws
Exception
// let's assume a collection of uris need to be processed and transformed to be simplified ;
// we want only http/https ones, only the host part and forcing an https scheme
List uris = Arrays.asList(
URI.create(
"http://user@www.apache.org:8000?qry=true"
),
URI.create(
"https://commons.apache.org/releases/prepare.html"
),
URI.create(
"mailto:henrib@apache.org"
);
// Create the test control, the expected result of our script evaluation
List control = uris.stream()
.map(uri -> uri.getScheme().startsWith(
"http"
)?
"https://"
+ uri.getHost() :
null
.filter(x -> x !=
null
.collect(Collectors.toList());
Assert.assertEquals(2, control.size());
// Create scripts:
// uri is the name of the variable used as parameter; the beans are exposed as properties
// note the starts-with operator =^
// note that uri is also used in the back-quoted string that performs variable interpolation
JexlScript mapper = jexl.createScript(
"uri.scheme =^ 'http'? `https://${uri.host}` : null"
"uri"
);
// using the bang-bang / !! - JScript like - is the way to coerce to boolean in the filter
JexlScript transform = jexl.createScript(
"list.stream().map(mapper).filter(x -> !!x).collect(Collectors.toList())"
"list"
);
// Execute scripts:
JexlContext sctxt =
new
StreamContext();
// expose the static methods of Collectors; java.util.* is allowed by permissions
sctxt.set(
"Collectors"
, Collectors.class);
// expose the mapper script as a global variable in the context
sctxt.set(
"mapper"
, mapper);

Object transformed = transform.execute(sctxt, uris);
Assert.assertTrue(transformed
instanceof
List);
Assert.assertEquals(control, transformed);
Extensions to JSTL Expression Language
JEXL attempts to bring some of the lessons learned by the Velocity
community about expression languages in templating to a wider audience.
Commons Jelly
needed
Velocity-ish method access, it just had to have it.
It must be noted that JEXL is
not
a compatible implementation of EL as defined
in JSTL 1.1 (JSR-052) or JSP 2.0 (JSR-152). For a compatible implementation of
these specifications, see the
Commons EL
project.
While JEXL 3.3 is now closer to JScript (without prototypes), its roots are the expression language defined in JSTL
and its has improved upon its syntax in a few areas:
Support for invocation of any accessible method (see example above).
Support for setting/getting any accessible public field.
A general
new()
method allowing to instantiate objects.
A general
size()
method, which works on:
String
- returns length
Map
- returns number of keys
List
- returns number of elements.
A general
empty()
method, which works on Collections and Strings.
Support for the ternary operator 'a ? b : c' - and its GNU-C / "Elvis" variant 'a ?: c'.
Support for the Perl-like regex matching operators '=~' and '!~'
Support for the CSS3-inspired 'startsWith' and 'endsWith' operators '=^' and '=$'
Support for user-defined functions.
Misc : '+' has been overloaded to be use as a String concatenation operator
Related Resources
JEXL is not a product of the Java Community Process (JCP), but it provides a
similar expression syntax. For more information about JSP 2.0 EL and JSTL 1.1
EL:
JSP 2.0
is covered
by Java Specification Requests (JSR)
JSR-152: JavaServer
Pages 2.0 Specification
Apache has an implementation of the expression language for JSP 2.0,
called
EL
JSTL 1.1
is covered
by
JSR 52: A Standard
Tag Library for JavaServer Pages
. See the
JSTL API
Apache has a
JSTL Implementation
Velocity
Apache Velocity
implements
a similar expression language.
In particular the
References
section of the User Guide has some good information on properties and method which correlate
directly to JEXL.
Projects Using Commons JEXL
Commons Configuration
Commons SCXML
Jelly
Copyright © 2001-2026
The Apache Software Foundation
Apache Commons, Apache Commons JEXL, Apache, the Apache logo, and the Apache Commons project logos are trademarks of The Apache Software Foundation.
All other marks mentioned may be trademarks or registered trademarks of their respective owners.