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 groupsfindFirst(predicate, [default])- Find the first matching element with optional defaultfirst([default])- Get the first element with optional default valueflatMap(mapper)- Map and flatten results in one operationflatten([depth])- Flatten nested arrays to specified depthgroupBy(property|function)- Group array elements by key or functionreject(predicate)- Filter out elements matching a condition (inverse offilter())transpose()- Convert rows to columns in 2D arraysunique([type])- Remove duplicate values with optional type comparisonzip(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 onjava.util.SetcollectionsBigDecimal/Long Support -
formatBaseN()now properly handlesjava.lang.Longtypes
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"formatFixed date equality issues in compatibility mode with different timezones
Resolved
falsebeing incorrectly cast to DateTime objects in compat mode
Query Component Enhancements
queryNew()now accepts columns as an array:queryNew( ["id", "name", "email"] )Relaxed
dbtypevalidation on query component for better CFML compatibilityFixed 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 processserver.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.Fileinstances[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=valueenv varsMore 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?
