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 valueBenefits:
No manual
listToArray()conversions neededConsistent 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()methodsPrevention 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
implementsinstead of string
File Operations
File Upload:
resultfield now properly populated after uploadContent Types: Upload
contentTypeno longer incorrectly includescontentSubTypeFile 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:
datepartparameter no longer case-sensitiveDateTime Parsing: Fixed casting issues with datetime formats like "Dec/13/2025 08:00"
Session and Cookie Handling
Session End Errors: Errors in
onSessionEndno longer leave session in permanently expired stateSession Prevention: Sessions no longer inadvertently start during application initialization
Cookie Serialization:
bx:cookienow serializes time in GMT as expected
Core Runtime Fixes
Duplicate:
duplicate()now properly handles recursive referencesExpandPath: 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:
SQL Parameter Validation: Integer SQL type now properly validates instead of silently truncating decimals. Update queries that incorrectly used integer type for decimal values:
Currency BIF Validation: Empty strings no longer accepted as currency codes:
Transaction Nested Attribute: The unused
nestedattribute 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
resultfield populationVerify datasource connection cleanup in long-running applications
Test session lifecycle if custom
onSessionEnderror 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-2005 Query object should not be building it's own metadata, the responsibility lies on the QueryMeta class
BL-2006 Ensure Doubles are converted to strings without using scientific notation
BL-2016 ignore unused procresult tags in Oracle
BL-2023 Consider removing the requirement to add multipart()
BL-2024 JDBC - Drop unused 'nested' boolean attribute from Transaction component
BL-2028 BoxLang Class Meta now has a static and abstract : boolean key for functions
BL-2033 preserve line breaks in doc comments
BL-2035 Allow web request context to detach from original exchange on shutdown if still in use
BL-2036 Add mechanism for contexts to keep a counter of how many threads are still using them
BL-2041 Run boxcache evictChecks during reap
BL-2045 Double caster should trim incoming strings
BL-2051 Improve error when announcing interceptions
BL-2052 Move ORM context removal to shutdown listener
BL-2061 Compat: SessionID in Session Scope is not prefixed with app identifier when J2EE sessions are enabled
BL-2062 Ensure proper app startup via runtime.executeXXX() methods
BL-2073 make count arg to mid() BIF optional
Bugs
BL-1756 Compat behavior - ListDeleteAt should retain leading delimiters
BL-1979 CreateUUID should return a standard UUID
BL-2000 cffile upload - `result` field not written to
BL-2003 cffile upload - resulting `contentType` should not also contain the `contentSubType`
BL-2007 Compat: Handle empty lists in cfqueryparam
BL-2008 compat: GetComponentMetaData returns string for implements versus object metadata
BL-2011 stored proc return code using wrong key name
BL-2012 Can't cast [Dec/13/2025 08:00] to a DateTime.
BL-2013 java class dump template error when it contains BoxClass field
BL-2014 Custom error type name hierarchy
BL-2015 Allow empty statement after constructs which require statement or body
BL-2018 compat-cfml - 'y' and 'n' are considered booleans
BL-2019 `datepart` in `dateAdd` is case sensitive
BL-2020 Oracle named params not working correctly
BL-2021 Oracle procs don't handle ref cursor out params which are not at the end of the list
BL-2022 SQL params using integer truncate decimal values instead of erroring
BL-2025 error when comparing null with LIKE operator in QoQ
BL-2027 ObjectMarshaller loses mappings when used directly with the correct context
BL-2029 bx-mail mail body missing when sending via secondary mailserver
BL-2032 yesClass interfaces meta was left as array in prime, when they should be struct
BL-2034 Doc comment immediately inside script isn't doesn't associate properly
BL-2037 redis cached query - java.io.NotSerializableException: ortus.boxlang.runtime.jdbc.DataSource
BL-2038 cfcookie should serialize time in terms of GMT
BL-2039 orm can't find datasources - Errors announcing [onTransactionBegin] interception
BL-2040 Application-level datasources not being shutdown when application ends
BL-2043 App caches aren't removed when the application ends
BL-2044 server level datasources are creating a pool for every application they are used in
BL-2047 BigDecimals serialize using scientific notation in JSON
BL-2048 scientific notation literals with leading zeros error
BL-2049 Comparison method violates its general contract!
BL-2050 UT010029: Stream is closed
BL-2053 GetHTTPTimeString should always be in GMT Timezone
BL-2054 Regression: Parsing of Common ODBC String Pattern fails to apply correct zone
BL-2055 Different listAppend() behavior
BL-2056 Error executing dump template on dump(application.wirebox)
BL-2057 Error in OnSessionEnd Can Leave the Session in a Permanently Expired and Non-Recoverable State
BL-2058 File Component action `append` Not Correctly Appending with New Lines
BL-2060 SOAP client not a class and does not have access to underlying HTTP methods
BL-2063 preserve whitespace eating too many line breaks
BL-2064 race conditions when two threads load the same class after source modification
BL-2066 duplicate() doesn't work with recursive references
BL-2067 prevent session from starting inside of application start method
BL-2068 expandPath() fails outside of a request (onServerStart)
BL-2069 Error sorting via store indexer Comparison method violates its general contract
BL-2070 Compat: Currency BIFs allow empty strings as currency code
BL-2071 Index -1 out of bounds for length 2 in reReplace()
BL-2072 for loop doesn't work on Java primitive array
BL-2074 evaluate() doesn't use CF transpiler when used in CF source
New Features
BL-1644 Support convention for parsing query params and form fields as array
BL-1999 Miniserver can now encapsulate settings in a miniserver.json for portability
Last updated
Was this helpful?
