githubEdit

1.9.0

January 8, 2026 - Happy New Year! BoxLang 1.9.0 is a significant stability and compatibility release, focusing on production-readiness through enhanced lifecycle management, comprehensive CFML compati

BoxLang 1.9.0 is a significant stability and compatibility release, focusing on production-readiness through enhanced lifecycle management, comprehensive CFML compatibility improvements, and critical bug fixes. This release introduces array-based form field parsing conventions, improved datasource lifecycle management, enhanced metadata capabilities, and resolves over 50 bugs to ensure rock-solid reliability for enterprise applications.

🚀 Major Highlights

📦 Array-Based Form Field Parsing Convention

BoxLang now supports automatic parsing of query parameters and form fields as arrays using naming conventions, making it easier to work with multiple values without manual parsing:

// HTML form with multiple checkboxes
<form method="POST">
    <input type="checkbox" name="colors[]" value="red" />
    <input type="checkbox" name="colors[]" value="blue" />
    <input type="checkbox" name="colors[]" value="green" />
    <button type="submit">Submit</button>
</form>

// BoxLang automatically parses as array
selectedColors = form.colors
// selectedColors is now an array: ["red", "blue", "green"]

// Works with query parameters too
// URL: /page?tags[]=boxlang&tags[]=java&tags[]=modern
tags = url.tags
// tags is now an array: ["boxlang", "java", "modern"]

// Traditional single values still work
name = form.name  // Single string value

Benefits:

  • No manual listToArray() conversions needed

  • Consistent with modern web framework conventions

  • Backward compatible with existing code

  • Works with both form fields and URL parameters

🔄 Enhanced Context Lifecycle Management

Significant improvements to context management and shutdown handling ensure proper cleanup and prevent resource leaks:

Context Thread Tracking: Contexts now maintain counters for active threads, preventing premature cleanup:

Key Improvements:

  • Web request contexts can detach from original exchange during shutdown

  • ORM context removal moved to shutdown listeners for proper cleanup

  • Session errors no longer leave sessions in permanently expired state

  • Proper application startup via runtime.executeXXX() methods

  • Prevention of session starts during application initialization

🧹 SOAP Client Improvements

The SOAP client introduced in 1.8.0 has been enhanced with proper class structure and HTTP method access:

🤖 Core Runtime Updates

🗄️ Datasource Lifecycle Management

Critical improvements to datasource lifecycle prevent resource leaks and connection pool issues:

Proper Shutdown Handling:

Fixed Issues:

  • Application-level datasources now shut down when application ends

  • Server-level datasources no longer create duplicate pools per application

  • Application caches properly removed on application end

  • Connection pool cleanup during application lifecycle

📊 Query and JDBC Enhancements

Comprehensive improvements to query handling and database operations:

Query Metadata Refactoring: Query metadata responsibility properly separated to QueryMeta class for better performance and maintainability.

Oracle Database Improvements:

Parameter Handling:

Query of Queries:

🔢 Number Handling Improvements

Significant enhancements to numeric type handling and serialization:

Scientific Notation Prevention:

Double Caster Improvements:

🎭 Enhanced Class Metadata

Class metadata now includes static and abstract flags for functions:

Additional Metadata Improvements:

  • Component metadata now returns struct for implements (not string)

  • Interface metadata properly structured in all scenarios

  • Doc comments preserve line breaks for better documentation

  • Doc comments immediately inside script blocks now associate properly

🔐 Transaction Component Cleanup

Removed unused nested boolean attribute from transaction component for cleaner API:

📡 MiniServer Runtime Updates

📄 JSON Configuration Support

MiniServer now supports loading configuration from JSON files (introduced in 1.8.0, finalized in 1.9.0):

Configuration Example:

🛠️ Developer Experience

🎯 Improved Error Messages

Better error reporting for interception announcements and general exceptions.

📝 Mid() Function Improvement

The mid() BIF now has optional count parameter for more flexible string extraction:

🔍 Better Class Inspection

Classes and Java class dumps improved with better error handling:

🐛 Notable Bug Fixes

CFML Compatibility Improvements

  • ListDeleteAt: Now retains leading delimiters for proper CFML compatibility

  • ListAppend: Behavior now matches CFML exactly

  • Boolean Strings: Characters 'y' and 'n' properly recognized as booleans in compat mode

  • Session IDs: SessionID in session scope properly prefixed with app identifier when J2EE sessions enabled

  • GetComponentMetaData: Returns proper struct for implements instead of string

File Operations

  • File Upload: result field now properly populated after upload

  • Content Types: Upload contentType no longer incorrectly includes contentSubType

  • File Append: action="append" now correctly appends with proper line breaks

String and List Operations

  • CreateUUID: Now returns standard UUID format

  • ReReplace: Fixed index out of bounds errors

  • DateAdd: datepart parameter no longer case-sensitive

  • DateTime Parsing: Fixed casting issues with datetime formats like "Dec/13/2025 08:00"

  • Session End Errors: Errors in onSessionEnd no longer leave session in permanently expired state

  • Session Prevention: Sessions no longer inadvertently start during application initialization

  • Cookie Serialization: bx:cookie now serializes time in GMT as expected

Core Runtime Fixes

  • Duplicate: duplicate() now properly handles recursive references

  • ExpandPath: Works correctly outside of request context (e.g., in onServerStart)

  • For Loops: Now work properly with Java primitive arrays

  • Evaluate: Properly uses CF transpiler when called from CF source

  • Whitespace: Preserve whitespace no longer consumes excessive line breaks

  • Class Loading: Fixed race conditions when multiple threads load the same class

Database and ORM

  • Redis Query Caching: Fixed serialization issues with cached queries

  • ORM Datasources: ORM can now properly find datasources without errors

  • Stored Procedure Return Codes: Now use correct key names

Memory and Threading

  • Stream Handling: Fixed "Stream is closed" errors (UT010029)

  • Context Threading: Proper handling of contexts with multiple active threads

  • Comparison Sorting: Fixed "Comparison method violates its general contract" errors

🔧 Configuration Updates

HTTP Multipart Simplification

HTTP file uploads no longer require explicit multipart() call in many cases:

⚡ Migration Notes

Breaking Changes

This release focuses on bug fixes and compatibility improvements with minimal breaking changes:

  1. SQL Parameter Validation: Integer SQL type now properly validates instead of silently truncating decimals. Update queries that incorrectly used integer type for decimal values:

  1. Currency BIF Validation: Empty strings no longer accepted as currency codes:

  1. Transaction Nested Attribute: The unused nested attribute has been removed from the transaction component. Simply remove any references to it as nesting is automatic.

Upgrade Recommendations

For Production Applications:

  • Review any custom SQL parameter handling that relied on integer truncation

  • Test file upload operations to verify new result field population

  • Verify datasource connection cleanup in long-running applications

  • Test session lifecycle if custom onSessionEnd error handling was implemented

For CFML Migrations:

  • List operations now match CFML behavior more closely - test list manipulation code

  • Session handling improved for J2EE compatibility - test session management

  • DateTime parsing enhanced - verify any custom date handling code

Performance Improvements:

  • Datasource connection pools no longer duplicated per application - may see memory improvements

  • Query metadata generation optimized - queries may execute slightly faster

  • Cache eviction more efficient - better memory utilization in cache-heavy applications


🎶 Release Notes

Improvements

BL-2005arrow-up-right Query object should not be building it's own metadata, the responsibility lies on the QueryMeta class

BL-2006arrow-up-right Ensure Doubles are converted to strings without using scientific notation

BL-2016arrow-up-right ignore unused procresult tags in Oracle

BL-2023arrow-up-right Consider removing the requirement to add multipart()

BL-2024arrow-up-right JDBC - Drop unused 'nested' boolean attribute from Transaction component

BL-2028arrow-up-right BoxLang Class Meta now has a static and abstract : boolean key for functions

BL-2033arrow-up-right preserve line breaks in doc comments

BL-2035arrow-up-right Allow web request context to detach from original exchange on shutdown if still in use

BL-2036arrow-up-right Add mechanism for contexts to keep a counter of how many threads are still using them

BL-2041arrow-up-right Run boxcache evictChecks during reap

BL-2045arrow-up-right Double caster should trim incoming strings

BL-2051arrow-up-right Improve error when announcing interceptions

BL-2052arrow-up-right Move ORM context removal to shutdown listener

BL-2061arrow-up-right Compat: SessionID in Session Scope is not prefixed with app identifier when J2EE sessions are enabled

BL-2062arrow-up-right Ensure proper app startup via runtime.executeXXX() methods

BL-2073arrow-up-right make count arg to mid() BIF optional

Bugs

BL-1756arrow-up-right Compat behavior - ListDeleteAt should retain leading delimiters

BL-1979arrow-up-right CreateUUID should return a standard UUID

BL-2000arrow-up-right cffile upload - `result` field not written to

BL-2003arrow-up-right cffile upload - resulting `contentType` should not also contain the `contentSubType`

BL-2007arrow-up-right Compat: Handle empty lists in cfqueryparam

BL-2008arrow-up-right compat: GetComponentMetaData returns string for implements versus object metadata

BL-2011arrow-up-right stored proc return code using wrong key name

BL-2012arrow-up-right Can't cast [Dec/13/2025 08:00] to a DateTime.

BL-2013arrow-up-right java class dump template error when it contains BoxClass field

BL-2014arrow-up-right Custom error type name hierarchy

BL-2015arrow-up-right Allow empty statement after constructs which require statement or body

BL-2018arrow-up-right compat-cfml - 'y' and 'n' are considered booleans

BL-2019arrow-up-right `datepart` in `dateAdd` is case sensitive

BL-2020arrow-up-right Oracle named params not working correctly

BL-2021arrow-up-right Oracle procs don't handle ref cursor out params which are not at the end of the list

BL-2022arrow-up-right SQL params using integer truncate decimal values instead of erroring

BL-2025arrow-up-right error when comparing null with LIKE operator in QoQ

BL-2027arrow-up-right ObjectMarshaller loses mappings when used directly with the correct context

BL-2029arrow-up-right bx-mail mail body missing when sending via secondary mailserver

BL-2032arrow-up-right yesClass interfaces meta was left as array in prime, when they should be struct

BL-2034arrow-up-right Doc comment immediately inside script isn't doesn't associate properly

BL-2037arrow-up-right redis cached query - java.io.NotSerializableException: ortus.boxlang.runtime.jdbc.DataSource

BL-2038arrow-up-right cfcookie should serialize time in terms of GMT

BL-2039arrow-up-right orm can't find datasources - Errors announcing [onTransactionBegin] interception

BL-2040arrow-up-right Application-level datasources not being shutdown when application ends

BL-2043arrow-up-right App caches aren't removed when the application ends

BL-2044arrow-up-right server level datasources are creating a pool for every application they are used in

BL-2047arrow-up-right BigDecimals serialize using scientific notation in JSON

BL-2048arrow-up-right scientific notation literals with leading zeros error

BL-2049arrow-up-right Comparison method violates its general contract!

BL-2050arrow-up-right UT010029: Stream is closed

BL-2053arrow-up-right GetHTTPTimeString should always be in GMT Timezone

BL-2054arrow-up-right Regression: Parsing of Common ODBC String Pattern fails to apply correct zone

BL-2055arrow-up-right Different listAppend() behavior

BL-2056arrow-up-right Error executing dump template on dump(application.wirebox)

BL-2057arrow-up-right Error in OnSessionEnd Can Leave the Session in a Permanently Expired and Non-Recoverable State

BL-2058arrow-up-right File Component action `append` Not Correctly Appending with New Lines

BL-2060arrow-up-right SOAP client not a class and does not have access to underlying HTTP methods

BL-2063arrow-up-right preserve whitespace eating too many line breaks

BL-2064arrow-up-right race conditions when two threads load the same class after source modification

BL-2066arrow-up-right duplicate() doesn't work with recursive references

BL-2067arrow-up-right prevent session from starting inside of application start method

BL-2068arrow-up-right expandPath() fails outside of a request (onServerStart)

BL-2069arrow-up-right Error sorting via store indexer Comparison method violates its general contract

BL-2070arrow-up-right Compat: Currency BIFs allow empty strings as currency code

BL-2071arrow-up-right Index -1 out of bounds for length 2 in reReplace()

BL-2072arrow-up-right for loop doesn't work on Java primitive array

BL-2074arrow-up-right evaluate() doesn't use CF transpiler when used in CF source

New Features

BL-1644arrow-up-right Support convention for parsing query params and form fields as array

BL-1999arrow-up-right Miniserver can now encapsulate settings in a miniserver.json for portability

Last updated

Was this helpful?