Class JexlConfigLoader

java.lang.Object
org.apache.commons.jexl3.JexlConfigLoader

public final class JexlConfigLoader extends Object
Loads a YAML configuration file and applies it to a JexlBuilder.

Quick start:

 try (InputStream in = getClass().getResourceAsStream("/jexl.yaml")) {
     JexlEngine engine = JexlConfigLoader.load(in).create();
 }
 

The loader understands a simple YAML subset: top-level scalars, one level of section nesting, and list items. No external YAML library is required. Inline comments (# after whitespace), empty lines, and single/double-quoted string values are supported.

Top-level scalar keys

These map directly to the matching JexlBuilder setter. Boolean values accept true/false, yes/no, or on/off. Example:

 strict: true         # JexlBuilder.strict(true)
 silent: false        # JexlBuilder.silent(false)
 safe: true           # JexlBuilder.safe(true)   — enable safe-navigation ?.
 cancellable: false   # JexlBuilder.cancellable(false)
 antish: true         # JexlBuilder.antish(true) — resolve ant-style dotted names
 lexical: true        # JexlBuilder.lexical(true)
 lexicalShade: false  # JexlBuilder.lexicalShade(false)
 strictInterpolation: false
 booleanLogical: false
 debug: true          # include source location in exceptions
 cache: 512           # expression cache size (entries)
 cacheThreshold: 64   # max expression length cached
 stackOverflow: 512   # max recursion depth
 collectMode: 1       # variable collection mode (0=off, 1=on)
 charset: UTF-8       # source charset for script text
 strategy: JEXL_STRATEGY   # property-resolver order: JEXL_STRATEGY or MAP_STRATEGY
 

permissions: section

Controls which classes and members are visible to scripts.

 permissions:
   base: SECURE           # NONE (default) | SECURE | RESTRICTED | UNRESTRICTED
   rules:                 # list of JexlPermissions DSL strings composed on top of base
     - "com.example.api +{}"           # allow whole package
     - "com.example.api +{ Foo{} }"    # allow specific class
     - "java.util +{ -Formatter { Formatter(); } }"  # deny one constructor
   classes:               # explicit fully-qualified class names to allow (ClassPermissions)
     - com.example.api.Foo
     - com.example.api.Bar
   logging: my.logger     # optional: wrap in LoggingPermissions; value = logger name
                          # bare "logging:" with no value uses the default logger
 

See JexlPermissions.parse(String...) for the DSL syntax, JexlPermissions.SECURE, JexlPermissions.RESTRICTED, JexlPermissions.logging() for the logging wrapper.

features: section

Controls which syntactic constructs are available at parse time. Each key is the name of a JexlFeatures boolean setter method; unknown keys are silently ignored.

 features:
   # Script structure
   script: true             # multi-statement scripts (vs. single-expression mode)
   localVar: true           # local variable declarations (var x = ...)
   lambda: true             # lambda / named-function definitions
   loops: true              # for / while / do-while loops
   newInstance: true        # new(...) constructor calls

   # Side-effects
   sideEffect: true         # any assignment or modification (=, +=, ...)
   sideEffectGlobal: true   # assignment to context / global variables

   # Literals and operators
   structuredLiteral: true  # array [], map {}, set {} literals; ranges a..b
   arrayReferenceExpr: true # non-constant array index expressions (x[f()])
   methodCall: true         # method calls on objects (obj.method())
   annotation: true         # @annotation statements
   pragma: true             # #pragma directives
   pragmaAnywhere: true     # allow #pragma anywhere (not just at the top)
   namespacePragma: true    # #pragma jexl.namespace.ns ... syntax
   namespaceIdentifier: true# ns:fun(...) compact namespace call syntax
   importPragma: true       # #pragma jexl.import ... syntax

   # Lambda arrow styles
   thinArrow: true          # thin-arrow lambdas  x -> x + 1
   fatArrow: true           # fat-arrow lambdas   x => x + 1

   # Variable capture semantics
   constCapture: true       # captured variables are read-only (Java-style)
   referenceCapture: false  # captured variables are pass-by-reference (ECMAScript-style)

   # Lexical scoping (also settable at top level via 'lexical:' / 'lexicalShade:')
   lexical: true
   lexicalShade: false

   # Misc
   comparatorNames: true    # allow 'gt', 'lt', 'ge', 'le', 'eq', 'ne' as operator aliases
   ambiguousStatement: true # allow statements that are syntactically ambiguous
   ignoreTemplatePrefix: false

   # Reserved names (list — cannot be used as local variable or parameter names)
   reservedNames:
     - try
     - catch
     - class
 

arithmetic: section

Selects and configures the JexlArithmetic implementation.

 arithmetic:
   clazz: org.apache.commons.jexl3.JexlArithmetic  # fully-qualified class (default)
   strict: true       # strict arithmetic (true = default); passed to the constructor
   mathContext: DECIMAL64   # java.math.MathContext field: DECIMAL32 | DECIMAL64 | DECIMAL128 | UNLIMITED
   mathScale: 10      # BigDecimal scale; requires mathContext; -1 = use context default
 

When mathContext is present the constructor (boolean, MathContext, int) is used; otherwise (boolean) is used. The class must be on the classpath.

namespaces: section

Maps namespace prefixes to fully-qualified class names. The class is loaded and passed to JexlBuilder.namespaces(java.util.Map). Its static (or instance) methods become callable as prefix:methodName(args) from scripts.

 namespaces:
   math: java.lang.Math          # math:abs(-1) etc.
   str:  com.example.StringUtils # str:trim(x) etc.
 

imports: section

A list of package or class names passed to JexlBuilder.imports(java.util.Collection). Imported packages allow unqualified class names in new(...) and type references.

 imports:
   - java.lang
   - java.util
   - com.example.api
 

Complete annotated example

Every flag is listed explicitly so the configuration does not depend on any library default (which may change between releases). The features: block below reproduces the pre-3.7 feature set (JexlFeatures.createDefault()).

 # Production engine — explicit permissions + legacy feature set
 strict: true
 safe: false
 cache: 512

 permissions:
   base: RESTRICTED
   rules:
     - "com.example.api +{}"
   logging: com.example.jexl.permissions  # log allow/deny at INFO once per element

 features:
   script: true
   localVar: true
   lambda: true
   loops: true
   newInstance: true
   sideEffect: true
   sideEffectGlobal: true
   structuredLiteral: true
   arrayReferenceExpr: true
   methodCall: true
   annotation: true
   pragma: true
   pragmaAnywhere: true
   namespacePragma: true
   importPragma: true
   namespaceIdentifier: false
   thinArrow: true
   fatArrow: false
   constCapture: false
   referenceCapture: false
   lexical: false
   lexicalShade: false
   comparatorNames: true
   ambiguousStatement: false
   ignoreTemplatePrefix: false

 namespaces:
   math: java.lang.Math

 imports:
   - java.lang
   - java.util
 
Since:
3.7.0
  • Method Details

    • load

      public static JexlBuilder load(InputStream in) throws IOException
      Loads configuration from a YAML InputStream (UTF-8) into a JexlBuilder.
      Parameters:
      in - YAML input; the caller is responsible for closing it
      Returns:
      a configured JexlBuilder
      Throws:
      IOException - if the stream cannot be read
    • load

      public static JexlBuilder load(Reader reader) throws IOException
      Loads configuration from a YAML Reader into a JexlBuilder.
      Parameters:
      reader - YAML input; the caller is responsible for closing it
      Returns:
      a configured JexlBuilder
      Throws:
      IOException - if the reader cannot be read
    • engine

      public static JexlEngine engine(InputStream in) throws IOException
      Convenience: loads YAML from in and creates the engine in one call.
      Parameters:
      in - YAML input; the caller is responsible for closing it
      Returns:
      a new JexlEngine configured from the YAML
      Throws:
      IOException - if the stream cannot be read