> For the complete documentation index, see [llms.txt](https://boxlang.ortusbooks.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://boxlang.ortusbooks.com/readme/release-history/1.10.0.md).

# 1.10.0

**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

```js
// 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:

```js
// Collection destructuring - (key, value)
data = { name: "Alice", age: 25, city: "NYC" }
for ( key, value in data ) {
    println( "#key#: #value#" )
}

// Array destructuring - (item, index)
colors = ["red", "green", "blue"]
for ( color, index in colors ) {
    println( "#index#: #color#" )
}

// Query destructuring
for ( row, index in myQuery ) {
    println( "Row #index#: #row.name#" )
}
```

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:

```js
// Distributed lock using cache provider
lock( name="processPayment", cache="redisCache", timeout=30 ) {
    // Critical section protected across all servers
    processPayment( orderId )
}

// Traditional local lock still works
lock( name="localLock", type="exclusive", timeout=10 ) {
    updateLocalResource()
}
```

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:

```js
// Load a single module
moduleService().loadModule( expandPath( "/plugins/myModule" ) )

// Load all modules from a directory
moduleService().loadModules( expandPath( "/extensions" ) )

// Check module status
if ( moduleService().hasModule( "myModule" ) ) {
    settings = moduleService().getModuleSettings( "myModule" )
}
```

### 🤖 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:

```js
// Application cache takes precedence over global cache
cache( "userSessions" )  // Looks for app-specific cache first, then global
```

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:

```json
{
  "warmupURLs": [
    "http://localhost:8080/api/health",
    "http://localhost:8080/admin/cache/prime"
  ],
  "web": {
    "http": {
      "enable": true,
      "port": 8080
    }
  }
}
```

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.

```bash
{
    "boxlang" : {
        "executable" : "commandbox"
    }
}
```

#### 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)

```js
println( "Running on PID: #server.java.pid#" )
println( "Using compiler: #server.boxlang.compiler#" )
```

#### JSR-223 Configuration

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

```bash
# Environment variable
export BOX_JSR223_TIMEOUT=30000

# System property
java -Dboxlang.jsr223.timeout=30000 -jar app.jar
```

### 🐛 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:

```js
// Old behavior (might round)
num = someDecimal

// New behavior (truncates)
num = someDecimal  // Truncates

// If you need rounding
num = round( someDecimal )
```

#### 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](https://ortussolutions.atlassian.net/browse/BL-2075) Remove Compat DateEquality BIF and update \`equals\` method in DateTime class for lenient comparison

[BL-2080](https://ortussolutions.atlassian.net/browse/BL-2080) Better error message when importing invalid BOXLANG\_setting=value env vars

[BL-2083](https://ortussolutions.atlassian.net/browse/BL-2083) Allow general numeric casting types which truncate by default

[BL-2103](https://ortussolutions.atlassian.net/browse/BL-2103) relax dbtype validation on query component

[BL-2114](https://ortussolutions.atlassian.net/browse/BL-2114) content component to chunk binary responses instead of writing in one go

[BL-2115](https://ortussolutions.atlassian.net/browse/BL-2115) Improve performance in FQN

[BL-2116](https://ortussolutions.atlassian.net/browse/BL-2116) Allow Lock Component to Accept a Cache Attribute and ILockableCacheProvider interface

[BL-2123](https://ortussolutions.atlassian.net/browse/BL-2123) ASM cleanup for split methods with try/catch

[BL-2127](https://ortussolutions.atlassian.net/browse/BL-2127) Allow len() to work on a java.util.Set

[BL-2128](https://ortussolutions.atlassian.net/browse/BL-2128) ModuleService methods to load modules

[BL-2130](https://ortussolutions.atlassian.net/browse/BL-2130) set/clear context classloader on scheduled task threads

[BL-2131](https://ortussolutions.atlassian.net/browse/BL-2131) compat - allow dupe UDF declarations in CF source

[BL-2146](https://ortussolutions.atlassian.net/browse/BL-2146) Remove trailing semicolons in Oracle SQL

#### Bugs

[BL-1505](https://ortussolutions.atlassian.net/browse/BL-1505) Rework splitting of large methods in ASM

[BL-1917](https://ortussolutions.atlassian.net/browse/BL-1917) Compat: urlEncodedFormat difference from lucee/acf

[BL-2017](https://ortussolutions.atlassian.net/browse/BL-2017) ASM won't compile closure inside ternary

[BL-2059](https://ortussolutions.atlassian.net/browse/BL-2059) Inheritance at Three Levels Loses Variables Scope when Function is assigned as a variable

[BL-2076](https://ortussolutions.atlassian.net/browse/BL-2076) \`false\` incorrectly being cast to DateTime objects when using \`.equals\` in compat mode

[BL-2079](https://ortussolutions.atlassian.net/browse/BL-2079) Regression: EqualsEquals and Compare in compat for dates is now failing with different timezones.

[BL-2081](https://ortussolutions.atlassian.net/browse/BL-2081) HTTP Timeout Error - BigDecimal cannot be cast to class java.lang.Integer

[BL-2085](https://ortussolutions.atlassian.net/browse/BL-2085) An expired BL+ license seems to kill the runtime

[BL-2086](https://ortussolutions.atlassian.net/browse/BL-2086) formatBaseN does not handle java.lang.long

[BL-2087](https://ortussolutions.atlassian.net/browse/BL-2087) cache() bif not using the context cache retrieval hierarchy

[BL-2088](https://ortussolutions.atlassian.net/browse/BL-2088) compat cache bifs, need to get the cache via the context to do cache hierarchies retrieval

[BL-2089](https://ortussolutions.atlassian.net/browse/BL-2089) Dump Template should not Represent \`byte\[]\` as an array in output

[BL-2090](https://ortussolutions.atlassian.net/browse/BL-2090) Passing java proxy to method calls no-arg constructor

[BL-2091](https://ortussolutions.atlassian.net/browse/BL-2091) timeout attribute is optional to cflock tag in Lucee

[BL-2094](https://ortussolutions.atlassian.net/browse/BL-2094) transpile once to one for replace/nocase

[BL-2095](https://ortussolutions.atlassian.net/browse/BL-2095) file member methods incorrectly accessible on java.io.File instances

[BL-2096](https://ortussolutions.atlassian.net/browse/BL-2096) getCanonicalPath() not preserving trailing slash on directories

[BL-2097](https://ortussolutions.atlassian.net/browse/BL-2097) val() fails with trailing hypen

[BL-2098](https://ortussolutions.atlassian.net/browse/BL-2098) http component fails when empty string passed for proxy server

[BL-2099](https://ortussolutions.atlassian.net/browse/BL-2099) queryNew() doesn't support columns as an array

[BL-2101](https://ortussolutions.atlassian.net/browse/BL-2101) application component should not allow a body

[BL-2102](https://ortussolutions.atlassian.net/browse/BL-2102) logger can be null in localizationutil

[BL-2104](https://ortussolutions.atlassian.net/browse/BL-2104) associate component needs to strip cf\_ prefix from baseTag

[BL-2105](https://ortussolutions.atlassian.net/browse/BL-2105) Duplicate Cookies being set with different paths

[BL-2110](https://ortussolutions.atlassian.net/browse/BL-2110) Error calling pseudo constructor when using getClassMetadata()

[BL-2117](https://ortussolutions.atlassian.net/browse/BL-2117) Metadata annotations missing on abstract UDFs

[BL-2118](https://ortussolutions.atlassian.net/browse/BL-2118) directoryCopy() mishandling trailing slashes in some cases

[BL-2119](https://ortussolutions.atlassian.net/browse/BL-2119) Interface Errors when Implementing Class does not set default when interface does

[BL-2121](https://ortussolutions.atlassian.net/browse/BL-2121) Injected UDFs have incorrect "current" template

[BL-2122](https://ortussolutions.atlassian.net/browse/BL-2122) UDF called from thread inside class loses class reference

[BL-2124](https://ortussolutions.atlassian.net/browse/BL-2124) Compat directoryCopy() overwrites by default

[BL-2129](https://ortussolutions.atlassian.net/browse/BL-2129) Compat variable attr is optional on execute component

[BL-2134](https://ortussolutions.atlassian.net/browse/BL-2134) New application timeout expiry was not cancelling on applicatoin.shutdown

[BL-2138](https://ortussolutions.atlassian.net/browse/BL-2138) struct assignment creating string keys instead of int keys

[BL-2141](https://ortussolutions.atlassian.net/browse/BL-2141) Parser issue with text operator between two interpolated vars

[BL-2142](https://ortussolutions.atlassian.net/browse/BL-2142) string hash collisions in structs

[BL-2145](https://ortussolutions.atlassian.net/browse/BL-2145) CreateTimeSpan Dropping Minutes Argument

#### New Features

[BL-276](https://ortussolutions.atlassian.net/browse/BL-276) Support for loop (key, value) in collection and (item, index) in lists

[BL-2084](https://ortussolutions.atlassian.net/browse/BL-2084) Create config util helper for getting/casting/defaulting/validating ad-hoc config

[BL-2100](https://ortussolutions.atlassian.net/browse/BL-2100) Allow env var/sys prop config options for JSR-223

[BL-2120](https://ortussolutions.atlassian.net/browse/BL-2120) January, 05 2026 17:39:13 -0600 date mask

[BL-2125](https://ortussolutions.atlassian.net/browse/BL-2125) New Array/Member Methods and improvements: chunk(), findFirst(), first( default ), flatMap(), flatten(), groupBy(), reject(), transpose() , unique(), zip()

[BL-2132](https://ortussolutions.atlassian.net/browse/BL-2132) Create a \`bin\` folder in the BoxLang home in preparation of CommandBox next for module binaries

[BL-2133](https://ortussolutions.atlassian.net/browse/BL-2133) Add server.java.pid to easy identify the java process

[BL-2137](https://ortussolutions.atlassian.net/browse/BL-2137) MiniServer support for warmup urls

[BL-2139](https://ortussolutions.atlassian.net/browse/BL-2139) Add server.boxlang.compiler to know which compiler you are on easily


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://boxlang.ortusbooks.com/readme/release-history/1.10.0.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
