githubEdit

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-2075arrow-up-right Remove Compat DateEquality BIF and update `equals` method in DateTime class for lenient comparison

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

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

BL-2103arrow-up-right relax dbtype validation on query component

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

BL-2115arrow-up-right Improve performance in FQN

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

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

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

BL-2128arrow-up-right ModuleService methods to load modules

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

BL-2131arrow-up-right compat - allow dupe UDF declarations in CF source

BL-2146arrow-up-right Remove trailing semicolons in Oracle SQL

Bugs

BL-1505arrow-up-right Rework splitting of large methods in ASM

BL-1917arrow-up-right Compat: urlEncodedFormat difference from lucee/acf

BL-2017arrow-up-right ASM won't compile closure inside ternary

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

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

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

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

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

BL-2086arrow-up-right formatBaseN does not handle java.lang.long

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

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

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

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

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

BL-2094arrow-up-right transpile once to one for replace/nocase

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

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

BL-2097arrow-up-right val() fails with trailing hypen

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

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

BL-2101arrow-up-right application component should not allow a body

BL-2102arrow-up-right logger can be null in localizationutil

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

BL-2105arrow-up-right Duplicate Cookies being set with different paths

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

BL-2117arrow-up-right Metadata annotations missing on abstract UDFs

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

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

BL-2121arrow-up-right Injected UDFs have incorrect "current" template

BL-2122arrow-up-right UDF called from thread inside class loses class reference

BL-2124arrow-up-right Compat directoryCopy() overwrites by default

BL-2129arrow-up-right Compat variable attr is optional on execute component

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

BL-2138arrow-up-right struct assignment creating string keys instead of int keys

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

BL-2142arrow-up-right string hash collisions in structs

BL-2145arrow-up-right CreateTimeSpan Dropping Minutes Argument

New Features

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

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

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

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

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

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

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

BL-2137arrow-up-right MiniServer support for warmup urls

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

Last updated

Was this helpful?