For the complete documentation index, see llms.txt. This page is also available as Markdown.

1.10.0

February 3, 2026

BoxLang 1.10.0 delivers substantial improvements to array manipulation, loop syntax, caching infrastructure, and developer tooling. This release introduces powerful functional programming capabilities with 9 new array methods, enhances loop syntax with destructuring support, and extends the caching system with distributed locking via cache providers. Performance optimizations, particularly in fully-qualified name resolution and ASM compilation, make this one of the most significant releases for developer productivity and application performance.

🚀 Major Highlights

🎯 Enhanced Array Manipulation

BoxLang 1.10.0 introduces 9 powerful new array methods that bring modern functional programming capabilities to your arrays:

  • chunk(size) - Split arrays into smaller groups

  • findFirst(predicate, [default]) - Find the first matching element with optional default

  • first([default]) - Get the first element with optional default value

  • flatMap(mapper) - Map and flatten results in one operation

  • flatten([depth]) - Flatten nested arrays to specified depth

  • groupBy(property|function) - Group array elements by key or function

  • reject(predicate) - Filter out elements matching a condition (inverse of filter())

  • transpose() - Convert rows to columns in 2D arrays

  • unique([type]) - Remove duplicate values with optional type comparison

  • zip(array2, [array3...]) - Combine multiple arrays element-wise

// Chunk for pagination
items = [ 1, 2, 3, 4, 5, 6, 7 ]
pages = items.chunk( 3 )  // [ [1,2,3], [4,5,6], [7] ]

// Find first match with default
users = [ {name:"Alice", age:25}, {name:"Bob", age:30} ]
admin = users.findFirst( (u) => u.role == "admin", {name:"Guest"} )

// Group data for reports
transactions.groupBy( "category" )  // Groups by category key
transactions.groupBy( (t) => t.amount > 100 ? "large" : "small" )

// Flatten nested structures
nested = [ [1, [2, 3]], [4, [5]] ]
nested.flatten()      // [1, 2, 3, 4, 5] - full flatten
nested.flatten( 1 )   // [1, [2, 3], 4, [5]] - one level only

// Zip arrays together
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]
combined = names.zip( ages )  // [ ["Alice", 25], ["Bob", 30], ["Charlie", 35] ]

// Transpose matrix
matrix = [ [1,2,3], [4,5,6] ]
matrix.transpose()  // [ [1,4], [2,5], [3,6] ]

🔄 For Loop Destructuring

The for loop component now supports elegant destructuring syntax for iterating over collections with both keys/values and items/indexes:

This feature eliminates the verbose structEach() and arrayEach() patterns while providing cleaner, more readable iteration code.

🔒 Distributed Cache Locking

The Lock component now integrates with cache providers that implement the ILockableCacheProvider interface, enabling distributed locking across multiple servers:

This enables safe concurrent operations in clustered environments without requiring external coordination systems. This requires a distributed cache provider like Redis or Couchbase that implements the locking interface.

📊 Module Service Enhancements

New module loading methods make it easier to dynamically manage BoxLang modules at runtime, especially from Java plugins or extensions:

🤖 Core Runtime Updates

Performance Improvements

  • FQN Resolution Performance - Significant optimization in fully-qualified name resolution, improving class loading and component instantiation

  • ASM Compilation - Reworked method splitting for large methods with try/catch blocks, improving compilation efficiency and reducing bytecode size

  • Content Component Streaming - Binary responses now use chunked transfer encoding instead of buffering entire response in memory

Type System Enhancements

  • Numeric Casting - General numeric casting now truncates by default for consistent behavior across integer conversions

  • Set Length Support - The len() function now works on java.util.Set collections

  • BigDecimal/Long Support - formatBaseN() now properly handles java.lang.Long types

Cache Hierarchy

The cache retrieval system now properly follows the context cache hierarchy:

This ensures application-level cache isolation while maintaining fallback to global caches.

Date/Time Improvements

  • New date mask support: "January, 05 2026 17:39:13 -0600" format

  • Fixed date equality issues in compatibility mode with different timezones

  • Resolved false being incorrectly cast to DateTime objects in compat mode

Query Component Enhancements

  • queryNew() now accepts columns as an array: queryNew( ["id", "name", "email"] )

  • Relaxed dbtype validation on query component for better CFML compatibility

  • Fixed Oracle SQL trailing semicolon removal

📡 MiniServer Runtime Updates

Warmup URLs

The MiniServer now supports warmup URLs to pre-initialize your application before serving production traffic:

Warmup requests execute sequentially during server startup, ensuring caches are populated, connections established, and critical initialization complete before the server accepts requests.

🛠️ Developer Experience

Binary Folder for Module Commands

BoxLang now creates a bin/ folder in the BoxLang home directory, preparing for future CommandBox integration where modules can provide their own CLI commands and binaries.

Runtime Introspection

Two new server scope variables aid debugging and runtime identification:

  • server.java.pid - The Java process ID, making it easy to identify the running JVM process

  • server.boxlang.compiler - Identifies which compiler is active (ASM, Java, or Noop)

JSR-223 Configuration

The JSR-223 scripting engine integration now supports environment variables and system properties for configuration, enabling containerized deployments:

🐛 Notable Bug Fixes

Compilation & ASM

  • [BL-1505] Reworked splitting of large methods in ASM compiler - fixes complex methods that previously failed to compile

  • [BL-2017] Fixed ASM compilation failure with closures inside ternary expressions

  • [BL-2094] Fixed double transpilation in string replace operations with nocase flag

  • [BL-2141] Resolved parser issue with text operator between two interpolated variables

Class & Component System

  • [BL-2059] Fixed inheritance at three levels losing variables scope when functions assigned as variables

  • [BL-2110] Resolved error calling pseudo constructor when using getClassMetadata()

  • [BL-2117] Fixed missing metadata annotations on abstract UDFs

  • [BL-2119] Interface errors when implementing class doesn't set defaults that interface specifies

  • [BL-2121] Injected UDFs now have correct "current" template reference

  • [BL-2122] UDF called from thread inside class no longer loses class reference

Struct & Collection Handling

  • [BL-2138] Fixed struct assignment creating string keys instead of integer keys

  • [BL-2142] Resolved string hash collisions in structs causing key conflicts

File & I/O Operations

  • [BL-2095] File member methods no longer incorrectly accessible on java.io.File instances

  • [BL-2096] getCanonicalPath() now preserves trailing slash on directories

  • [BL-2118] Fixed directoryCopy() mishandling trailing slashes in some cases

  • [BL-2124] Compat mode directoryCopy() now overwrites by default for CFML compatibility

HTTP & Networking

  • [BL-2081] Fixed HTTP timeout error with BigDecimal to Integer casting

  • [BL-2098] HTTP component no longer fails when empty string passed for proxy server

  • [BL-2105] Resolved duplicate cookies being set with different paths

Compatibility Mode Fixes

  • [BL-1917] Fixed urlEncodedFormat() differences from Lucee/ACF

  • [BL-2079] Regression fix for date equality with different timezones in compat mode

  • [BL-2088] Compat cache BIFs now properly use context cache retrieval hierarchy

  • [BL-2091] Timeout attribute is now optional on lock tag in Lucee compat mode

  • [BL-2129] Variable attribute is now optional on execute component in compat mode

  • [BL-2131] Compat mode now allows duplicate UDF declarations in CF source files

Other Fixes

  • [BL-2085] Expired BoxLang+ license no longer kills the runtime

  • [BL-2089] Dump template no longer represents byte[] as array in output

  • [BL-2090] Fixed Java proxy calling no-arg constructor incorrectly

  • [BL-2097] val() no longer fails with trailing hyphen

  • [BL-2099] queryNew() now supports columns as array

  • [BL-2102] Fixed null logger in LocalizationUtil

  • [BL-2104] Associate component now strips cf_ prefix from baseTag properly

  • [BL-2134] Application timeout expiry now properly cancels on application.shutdown()

  • [BL-2145] Fixed createTimeSpan() dropping minutes argument

🔧 Configuration Updates

Config Utility Helper

New configuration utility helper for getting, casting, defaulting, and validating ad-hoc config values. This standardizes configuration handling across the runtime and modules.

Environment Variable Improvements

  • Better error messages when importing invalid BOXLANG_setting=value env vars

  • More consistent environment variable processing during server startup

⚡ Migration Notes

Array Method Name Changes

If you were using any pre-release versions of the new array methods, verify the method names match the final API. All new methods follow consistent naming conventions.

Loop Syntax Enhancement

The new destructuring syntax for (key, value in struct) is additive - existing loop syntax continues to work unchanged. Gradually adopt the new syntax where it improves readability.

Cache Locking

The new distributed cache locking requires cache providers that implement ILockableCacheProvider. Standard BoxLang caches and the default cache implementation do not support distributed locking - you must use a cache provider like Redis or Hazelcast that implements this interface.

Numeric Casting Behavior

General numeric casting now truncates by default. If you rely on rounding behavior, explicitly use round() before casting:

Oracle SQL

The runtime now automatically removes trailing semicolons from Oracle SQL statements. If you have workarounds for this in your code, you can remove them.


🎶 Release Notes

Improvements

BL-2075 Remove Compat DateEquality BIF and update `equals` method in DateTime class for lenient comparison

BL-2080 Better error message when importing invalid BOXLANG_setting=value env vars

BL-2083 Allow general numeric casting types which truncate by default

BL-2103 relax dbtype validation on query component

BL-2114 content component to chunk binary responses instead of writing in one go

BL-2115 Improve performance in FQN

BL-2116 Allow Lock Component to Accept a Cache Attribute and ILockableCacheProvider interface

BL-2123 ASM cleanup for split methods with try/catch

BL-2127 Allow len() to work on a java.util.Set

BL-2128 ModuleService methods to load modules

BL-2130 set/clear context classloader on scheduled task threads

BL-2131 compat - allow dupe UDF declarations in CF source

BL-2146 Remove trailing semicolons in Oracle SQL

Bugs

BL-1505 Rework splitting of large methods in ASM

BL-1917 Compat: urlEncodedFormat difference from lucee/acf

BL-2017 ASM won't compile closure inside ternary

BL-2059 Inheritance at Three Levels Loses Variables Scope when Function is assigned as a variable

BL-2076 `false` incorrectly being cast to DateTime objects when using `.equals` in compat mode

BL-2079 Regression: EqualsEquals and Compare in compat for dates is now failing with different timezones.

BL-2081 HTTP Timeout Error - BigDecimal cannot be cast to class java.lang.Integer

BL-2085 An expired BL+ license seems to kill the runtime

BL-2086 formatBaseN does not handle java.lang.long

BL-2087 cache() bif not using the context cache retrieval hierarchy

BL-2088 compat cache bifs, need to get the cache via the context to do cache hierarchies retrieval

BL-2089 Dump Template should not Represent `byte[]` as an array in output

BL-2090 Passing java proxy to method calls no-arg constructor

BL-2091 timeout attribute is optional to cflock tag in Lucee

BL-2094 transpile once to one for replace/nocase

BL-2095 file member methods incorrectly accessible on java.io.File instances

BL-2096 getCanonicalPath() not preserving trailing slash on directories

BL-2097 val() fails with trailing hypen

BL-2098 http component fails when empty string passed for proxy server

BL-2099 queryNew() doesn't support columns as an array

BL-2101 application component should not allow a body

BL-2102 logger can be null in localizationutil

BL-2104 associate component needs to strip cf_ prefix from baseTag

BL-2105 Duplicate Cookies being set with different paths

BL-2110 Error calling pseudo constructor when using getClassMetadata()

BL-2117 Metadata annotations missing on abstract UDFs

BL-2118 directoryCopy() mishandling trailing slashes in some cases

BL-2119 Interface Errors when Implementing Class does not set default when interface does

BL-2121 Injected UDFs have incorrect "current" template

BL-2122 UDF called from thread inside class loses class reference

BL-2124 Compat directoryCopy() overwrites by default

BL-2129 Compat variable attr is optional on execute component

BL-2134 New application timeout expiry was not cancelling on applicatoin.shutdown

BL-2138 struct assignment creating string keys instead of int keys

BL-2141 Parser issue with text operator between two interpolated vars

BL-2142 string hash collisions in structs

BL-2145 CreateTimeSpan Dropping Minutes Argument

New Features

BL-276 Support for loop (key, value) in collection and (item, index) in lists

BL-2084 Create config util helper for getting/casting/defaulting/validating ad-hoc config

BL-2100 Allow env var/sys prop config options for JSR-223

BL-2120 January, 05 2026 17:39:13 -0600 date mask

BL-2125 New Array/Member Methods and improvements: chunk(), findFirst(), first( default ), flatMap(), flatten(), groupBy(), reject(), transpose() , unique(), zip()

BL-2132 Create a `bin` folder in the BoxLang home in preparation of CommandBox next for module binaries

BL-2133 Add server.java.pid to easy identify the java process

BL-2137 MiniServer support for warmup urls

BL-2139 Add server.boxlang.compiler to know which compiler you are on easily

Last updated

Was this helpful?