1.8.0

December 5, 2025

BoxLang 1.8.0 is a massive release bringing revolutionary HTTP/SOAP capabilities, comprehensive CFML compatibility improvements, and critical stability enhancements. This release introduces a completely rewritten HTTP component with fluent APIs, streaming support, and persistent connection management, alongside a powerful SOAP/WSDL client for web service integration. With over 100 bug fixes and improvements, this release focuses on production-readiness, CFML migration compatibility, and modern web application development patterns.

🚀 Major Highlights

🎯 Modular Compiler Architecture & Ultra-Slim Runtime

BoxLang 1.8.0 introduces a revolutionary modular compiler architecture that delivers unprecedented flexibility, security, and deployment efficiency for enterprise applications.

🪶 Mega-Slim 7MB Runtime

The BoxLang runtime has been dramatically optimized, dropping from over 9MB to just 7MB by removing the JavaParser compiler dependencies. This lean footprint provides:

  • 22% Smaller runtime for faster downloads and deployments

  • Reduced memory footprint for containerized environments

  • Faster startup times due to smaller classpath

  • Improved security surface with fewer dependencies

🔐 Two Deployment Flavors for Enterprise Security

BoxLang now ships in two distinct flavors to meet different security and deployment requirements:

1. boxlang - Full Development Runtime

  • Includes NoOp (No Operation) compiler for pre-compiled class execution

  • Includes ASM compiler for runtime compilation and hot-reloading

  • Perfect for development, testing, and dynamic environments

  • Enables live code changes and interactive development

  • Default choice for most applications

2. boxlang-noop - Secure Production Runtime

  • NoOp compiler only - no runtime compilation capabilities

  • 100% pre-compiled code execution - zero dynamic compilation

  • Maximum security - eliminates runtime code injection vectors

  • Compliance-ready for regulated industries (finance, healthcare, government)

  • Reduced attack surface - no compiler means no compilation exploits

  • Immutable deployments - code cannot be modified at runtime

  • Perfect for production environments requiring security certifications

# Development/Standard deployment
java -jar boxlang-1.8.0.jar myapp.bx

# Secure production deployment (pre-compiled only)
java -jar boxlang-noop-1.8.0.jar myapp.bx

🔌 Plug-and-Play Compiler Modules

Compilers are now modular add-ons that can be loaded dynamically via classpath. BoxLang includes two compiler modules:

1. bx-compiler-asm - ASM Bytecode Compiler (Recommended)

  • Direct bytecode generation using ASM library

  • Superior performance - skips Java source generation step

  • Modern JVM feature support (virtual threads, pattern matching, etc.)

  • Optimized bytecode output

  • Default compiler for production applications

2. bx-compiler-java - Java Source Compiler

  • Generates Java source code, then compiles to bytecode

  • Legacy compatibility for debugging and inspection

  • Useful for understanding compilation process

  • Primarily for backward compatibility

// boxlang.json - Choose your compiler
{
  "compiler": "asm",  // Use ASM compiler (default)
  // OR
  "compiler": "java"  // Use Java source compiler
}

🚀 Revolutionary IBoxpiler Interface

The new IBoxpiler interface enables true plug-and-play compiler development:

public interface IBoxpiler {
    // Compile BoxLang source to bytecode
    byte[] compile( SourceCode source );

    // Get compiler metadata
    String getName();
    String getVersion();
}

What This Means:

  • 🔧 Custom Compilers - Build specialized compilers for your needs

  • 🎯 Domain-Specific Optimization - Create industry-specific compilation strategies

  • 🔒 Security Compilers - Implement compliance-specific compilation rules

  • Performance Compilers - Optimize for specific deployment targets

  • 🌐 Alternative Targets - Compile BoxLang to JavaScript, WASM, native code, etc.

  • 🔬 Research & Innovation - Experiment with new compilation techniques

Example Use Cases:

// Financial services: Compiler with embedded audit logging
compiler = new AuditCompiler()
    .enableTracing()
    .logToCompliance( "audit.log" );

// IoT: Compiler optimized for embedded devices
compiler = new EmbeddedCompiler()
    .optimizeForMemory()
    .targetArch( "ARM64" );

// Blockchain: Compiler with cryptographic verification
compiler = new VerifiableCompiler()
    .signOutput()
    .enableProofOfCompilation();

💼 Enterprise Benefits

Security & Compliance:

  • ✅ Deploy boxlang-noop for zero-runtime-compilation security posture

  • ✅ Meet PCI-DSS, HIPAA, SOC 2 requirements with immutable runtimes

  • ✅ Pass security audits with no dynamic code execution capabilities

  • ✅ Eliminate entire classes of code injection vulnerabilities

Performance & Efficiency:

  • 7MB runtime for lightning-fast container deployments

  • 🚀 Faster startup times in serverless and microservices

  • 💰 Lower cloud costs with smaller images and faster scaling

  • 🎯 Optimized memory usage for high-density deployments

Flexibility & Innovation:

  • 🔌 Plug-and-play compilers via IBoxpiler interface

  • 🛠️ Custom compilation strategies for specialized requirements

  • 🌐 Future-proof architecture supporting new compilation targets

  • 🔬 Research-friendly for academic and innovation projects

Deployment Scenarios:

Scenario
Recommended Runtime
Compiler

Development

boxlang

ASM (hot-reload enabled)

CI/CD Testing

boxlang

ASM

Staging

boxlang or boxlang-noop

ASM

Production (Standard)

boxlang

ASM

Production (High Security)

boxlang-noop

None (pre-compiled only)

Regulated Industries

boxlang-noop

None (pre-compiled only)

Government/Military

boxlang-noop

None (pre-compiled only)

Containerized Apps

boxlang-noop

None (smaller images)

Migration Path: Existing applications continue to work seamlessly. Simply choose boxlang for standard deployments or upgrade to boxlang-noop when security requirements demand pre-compiled-only execution.

🎓 Technical Details

The modular compiler architecture leverages:

  • Service Provider Interface (SPI) for compiler discovery

  • Classpath-based loading for dynamic compiler registration

  • Graceful fallback to NoOp if no compilers available

  • Zero-overhead abstraction - no performance penalty

  • Thread-safe compilation for concurrent applications

This architectural revolution positions BoxLang as the most flexible, secure, and enterprise-ready dynamic JVM language, with unparalleled deployment options for modern cloud-native applications.


🌐 Revolutionary HTTP Client & Component

The HTTP subsystem has been completely rewritten to provide modern, fluent HTTP capabilities with streaming support, connection management, and advanced features for building robust web applications.

New http() BIF - Fluent HTTP Client

A new http() BIF provides a fluent, chainable interface for building and executing HTTP requests with comprehensive configuration options:

// Simple GET request with fluent API
result = http( "https://api.example.com/data" ).send();
println( "Status: #result.statusCode#" );
println( "Body: #result.fileContent#" );

// Or send async and receive a box future
boxFuture = http( "https://api.example.com/data" )
    .get()
    .sendAsync()

// POST with JSON body
result = http( "https://api.example.com/users" )
    .post()
    .header( "Content-Type", "application/json" )
    .body( { name: "John Doe", email: "[email protected]" } )
    .send();
println( "User created: #result.fileContent#" );

// File upload with multipart
http( "https://api.example.com/upload" )
    .post()
    .multipart()
    .file( "document", "/path/to/file.pdf" )
    .formField( "description", "Important document" )
    .send();

// Stream large response with chunking
http( "https://api.example.com/large-data" )
    .get()
    .onChunk( ( chunk ) => {
        // Process each chunk as it arrives
        println( "Received chunk: #chunk.data.len()# bytes" );
    } )
    .send();

// Consume Server-Sent Events (SSE)
http( "https://api.example.com/events" )
    .get()
    .header( "Accept", "text/event-stream" )
    .onChunk( ( event ) => {
        // Process SSE events in real-time
        println( "Event: #event.event#" );
        println( "Data: #event.data#" );
    } )
    .send();

// Configure connection settings
result = http( "https://api.example.com/data" )
    .connectionTimeout( 30 )
    .httpVersion( "HTTP/2" )
    .redirect( true )
    .proxyServer( "proxy.company.com", 8080 )
    .clientCert( "/path/to/cert.p12", "password" )
    .get()
    .send();

// Transform response with custom function
users = http( "https://api.example.com/users" )
    .get()
    .transform( ( result ) => deserializeJSON( result.fileContent ) )
    .send(); // Returns deserialized array instead of result struct

Key Features:

  • Fluent API: Chainable methods for readable request building

  • Simple Execution: send() method executes request and returns result struct directly

  • Response Transformation: transform() method applies custom transformations to results before returning

  • HTTP/2 Support: Modern HTTP/2 by default with HTTP/1.1 fallback

  • Streaming: Chunk-based streaming for large responses and SSE

  • Connection Pooling: Automatic connection reuse and management

  • Client Certificates: SSL/TLS client certificate authentication

  • Proxy Support: HTTP/HTTPS proxy with authentication

  • Callbacks: Rich callback system (onChunk, onError, onComplete, onRequestStart)

  • Error Handling: throwOnError option automatically throws exceptions for HTTP errors (4xx/5xx)

Completely Rewritten bx:http Component

The bx:http component has been completely rewritten to match the fluent BIF capabilities while maintaining CFML compatibility:

// Simple GET request
<bx:http url="https://api.example.com/data" result="apiResult" />
<bx:dump var="#apiResult.statusCode#" />

// POST with JSON
<bx:http
    method="POST"
    url="https://api.example.com/users"
    result="response"
    throwOnError="true">
    <bx:httpparam type="header" name="Content-Type" value="application/json" />
    <bx:httpparam type="body" value='{"name":"John","email":"[email protected]"}' />
</bx:http>

// File upload (multipart)
<bx:http
    method="POST"
    url="https://api.example.com/upload"
    multipart="true">
    <bx:httpparam type="file" name="document" file="/path/to/file.pdf" />
    <bx:httpparam type="formfield" name="description" value="Important document" />
</bx:http>

// Download file
<bx:http
    url="https://example.com/downloads/report.pdf"
    file="report.pdf"
    path="/downloads/"
    getAsBinary="yes" />

// Streaming with callbacks
<bx:http
    url="https://api.example.com/stream"
    onChunk="#( chunk ) => processChunk( chunk )#"
    onError="#( error ) => logError( error )#"
    onComplete="#() => println( 'Stream complete' )#" />

// Server-Sent Events (SSE)
<bx:http
    url="https://api.example.com/events"
    sse="true"
    onMessage="#( event ) => handleSSEEvent( event )#" />

// Client certificate authentication
<bx:http
    url="https://secure-api.com/data"
    clientCert="/path/to/cert.p12"
    clientCertPassword="secret" />

// Proxy configuration
<bx:http
    url="https://external-api.com"
    proxyServer="proxy.company.com"
    proxyPort="8080"
    proxyUser="username"
    proxyPassword="password" />

New Features:

  • Streaming Callbacks: onChunk, onMessage, onError, onComplete, onRequestStart

  • SSE Support: Native Server-Sent Events handling with sse attribute

  • HTTP/2: Full HTTP/2 support with httpVersion attribute

  • Connection Management: Persistent connections and connection pooling

  • Client Certificates: SSL/TLS client certificate authentication

  • Better Error Handling: throwOnError attribute for automatic exception throwing

HTTP Service - Connection Lifecycle Management

A new HttpService manages HTTP client instances, connection pooling, and lifecycle:

// Clients are automatically managed and reused based on configuration
client1 = http( "https://api.example.com" );
client2 = http( "https://api.example.com" ); // Reuses same connection pool

// Access HTTP statistics
stats = getBoxRuntime().getHttpService().getStats();
println( "Total requests: #stats.totalRequests#" );
println( "Active connections: #stats.activeConnections#" );

Features:

  • Automatic connection pooling and reuse

  • Connection lifecycle management

  • Statistics tracking (requests, failures, bytes transferred)

  • Graceful shutdown with connection draining

🧼 SOAP/WSDL Client Integration

BoxLang now includes comprehensive SOAP web service support with automatic WSDL parsing and fluent method invocation:

New soap() BIF

A new soap() BIF provides easy SOAP client creation:

// Create SOAP client from WSDL using soap() BIF
ws = soap( "http://example.com/service.wsdl" );

// Configure client settings
ws = soap( "http://example.com/service.wsdl" )
    .timeout( 60 )
    .withBasicAuth( "username", "password" )
    .header( "X-Custom-Header", "value" );

// Invoke methods directly (discovered from WSDL)
result = ws.getUserInfo( userID: 123 );
println( "User: #result.name#" );

// Alternative: createObject() syntax (traditional)
ws = createObject( "webservice", "http://example.com/service.wsdl" );
result = ws.getUserInfo( userID: 123 );

// Use invoke() function for dynamic calls
result = invoke( ws, "getUserInfo", { userID: 123 } );

// Use in components
<bx:invoke
    webservice="http://example.com/service.wsdl"
    method="getUserInfo"
    userID="123"
    returnVariable="userInfo" />

// Inspect available operations
operations = ws.getOperationNames();
println( "Available operations: #operations.toList()#" );

// Get operation details
opInfo = ws.getOperationInfo( "getUserInfo" );
println( "Parameters: #opInfo.parameters.toList()#" );

Features:

  • Automatic WSDL Parsing: Discovers methods, parameters, and types

  • SOAP 1.1 & 1.2 Support: Auto-detects version from WSDL

  • Fluent Method Calls: Invoke methods directly on client object

  • Response Unwrapping: Automatically unwraps single-property response structures

  • Document/Literal Wrapped: Full support for document/literal wrapped style

  • Parameter Handling: Automatic parameter type conversion and validation

  • Automatic BoxLang Type Mapping: Maps SOAP types to BoxLang types automatically

Implementation Details:

  • Parses WSDL using DOM XML parser

  • Extracts operations, bindings, and port types

  • Handles XSD schema for parameter discovery

  • Builds SOAP envelopes dynamically

  • Supports complex types and nested structures

  • Compatible with invoke() BIF and bx:invoke component

🎯 Context Shutdown Listeners

New lifecycle hooks for graceful application shutdown:

// In Application.bx
component {
    this.name = "MyApp";

    function onApplicationStart() {
        // Register shutdown listener
        application.resources = setupResources();

        getBoxContext().registerShutdownListener( () => {
            // Clean up resources on shutdown
            application.resources.close();
            println( "Application shutdown complete" );
        } );
    }
}

Use Cases:

  • Database connection cleanup

  • Cache flushing

  • File handle closing

  • External service disconnection

  • Logging final state

📚 Enhanced Metadata & Reflection

Class metadata now includes simpleName for easier reflection:

meta = getMetadata( myObject );
println( "Class: #meta.fullName#" );
println( "Simple name: #meta.simpleName#" ); // New in 1.8.0

🤖 Core Runtime Updates

Configuration Improvements

Compiler Configuration: The experimental compiler setting has been refactored to a top-level directive in boxlang.json:

{
  "compiler": "asm",  // or "java" or "noop"
  "runtime": {
    // other runtime settings
  }
}

JDBC URL Enhancements:

  • More robust placeholder replacements

  • Case-insensitive placeholder matching

  • Support for complex JDBC URL patterns

Dynamic Class Loading

The DynamicClassLoader has been enhanced with addPaths() method for dynamically loading JAR files anywhere in your BoxLang source:

// Load external JARs at runtime
getRequestClassLoader().addPaths( [ "/path/to/library.jar", "/path/to/another.jar" ] );

// Now load classes from those JARs
MyClass = createObject( "java", "com.example.MyClass", getRequestClassLoader() );

Performance Optimizations

  • Metadata Creation: Micro-optimizations using imperative programming for faster class metadata generation

  • Application Timeout Checks: Now use background thread to reduce main thread overhead

  • Thread Joining: Faster bx:thread join operations

Query Improvements

  • Text Type Support: Query columns now support text type (maps to VARCHAR)

  • BLOB/CLOB Handling: Proper support for binary large objects

  • Column Type Tracking: Original JDBC column types preserved in query metadata

  • Oracle Improvements:

    • VARCHAR params now match CHAR fields correctly

    • Support for generated keys (ROWID)

    • Stored procedure ref cursor support

📡 MiniServer Runtime Updates

JSON Configuration Support

The BoxLang MiniServer now supports loading configuration from a JSON file, allowing you to store all server settings in one place instead of passing them as command-line arguments:

Automatic Loading:

# Looks for miniserver.json in current directory
boxlang-miniserver

Explicit Path:

boxlang-miniserver /path/to/config.json

Override with CLI:

# CLI arguments override JSON configuration
boxlang-miniserver miniserver.json --port 9090 --debug

Example Configuration Files:

// Basic configuration
{
  "port": 8080,
  "webRoot": "./www"
}

// Development configuration
{
  "port": 8080,
  "host": "127.0.0.1",
  "webRoot": "./src/webapp",
  "debug": true,
  "rewrites": true,
  "rewriteFileName": "index.bxm"
}

// Production configuration
{
  "port": 80,
  "host": "0.0.0.0",
  "webRoot": "/var/www/myapp",
  "debug": false,
  "rewrites": true,
  "rewriteFileName": "index.bxm",
  "healthCheck": true,
  "healthCheckSecure": true,
  "serverHome": "/opt/boxlang",
  "envFile": "/etc/boxlang/.env.production"
}

Supported Configuration Options:

Option
Type
Default
Description

port

number

8080

The port to listen on

host

string

"0.0.0.0"

The host to bind to

webRoot

string

current directory

Path to the webroot directory

debug

boolean

false

Enable debug mode

configPath

string

null

Path to BoxLang configuration file

serverHome

string

null

BoxLang server home directory

rewrites

boolean

false

Enable URL rewrites

rewriteFileName

string

"index.bxm"

Rewrite target file

healthCheck

boolean

false

Enable health check endpoints

healthCheckSecure

boolean

false

Restrict detailed health info to localhost only

envFile

string

null

Path to custom environment file (relative or absolute)

Configuration Priority:

Configuration values are loaded in the following order (later sources override earlier ones):

  1. Default values - Built-in defaults

  2. Environment variables - BOXLANG_* environment variables

  3. JSON configuration - Values from the JSON file

  4. Command-line arguments - Explicit CLI flags

For example, if you have:

  • Environment variable: BOXLANG_PORT=3000

  • JSON file: "port": 8080

  • CLI argument: --port 9090

The server will start on port 9090 (CLI overrides all).

Environment File Loading:

The envFile option allows you to specify a custom environment file to load:

{
  "envFile": ".env.local"
}

or

{
  "envFile": "/etc/myapp/.env.production"
}
  • If envFile is not specified, the server looks for .env in the webroot directory (default behavior)

  • If envFile is specified, it loads that file instead

  • The path can be relative (resolved from current directory) or absolute

  • Environment variables are loaded as system properties and can be used throughout the application

Other Improvements

  • Fixed rewrite handling: No longer unnecessarily rewrites file extensions

  • Request body improvements: Better handling of empty request bodies

  • Error messages: Enhanced error reporting for malformed requests

🤖 Servlet Runtime Updates

  • Real page context: Servlet runtime now uses proper page context (fixes many edge cases)

  • Relative path resolution: Fixed mapping path resolution issues

  • BOXLANG_DEBUG environment variable: Now properly supported

  • Session management: Fixed jsessionid cookie handling (prevents AWS WAF issues)

  • Concurrent request handling: Better handling of in-progress onApplicationStart()

🚀 AWS Lambda Runtime Updates

  • AWS Lambda Java Core upgraded from 1.3.0 to 1.4.0

🛠️ Developer Experience

JavaParser Dependencies

Removed all JavaParser dependencies externally unless explicitly checked. This reduces runtime footprint and startup time for applications that don't use Java source parsing features.

Feature Audit Tool

  • Enhanced to find REST classes and REST API usage

  • Better reporting of missing modules for migrations

  • Improved analysis of BoxLang feature usage

Web Support Documentation

All web-related BIFs and components now include proper descriptions via @BoxBIF and @BoxComponent annotations for better IDE integration and documentation generation.

🐛 Notable Bug Fixes

Date & Time (30+ fixes)

  • Timezone Handling: this.timezone now properly respected in Application.bx

  • Date Parsing: Fixed parsing issues with various date masks:

    • "Nov-05-2025 8:43am"

    • "Jun-30-2010 04:33"

    • "Jun-3-2010 04:33"

    • "11/21/2025 1:05"

    • "Jul 17, 2017 9:29:40 PM"

  • dateAdd(): No longer mutates date when adding 0 weeks

  • isDate(): Fixed various edge cases:

    • isDate(0) now returns false

    • Handles scientific notation strings

    • Better handling of invalid numeric strings

  • Date Casting: Fixed issues with JVM locales de_DE and en_DE

  • dateConvert(): Resolved conversion errors

  • timeFormat(): Fixed non-ASCII whitespace in output

  • Null Dates: Added handling for null dates in formatting methods

  • DateTime Optimization: DateTimeFormatter usage optimized for better performance

  • .format() Member: Undocumented but now properly supported on DateTime objects

Query Operations (15+ fixes)

  • queryFilter(): Fixed returning unexpected rows

  • querySlice(): Fixed offset handling

  • structFindKey(): Now returns proper references (not copies)

  • structFindValue(): Fixed crashes when keys contain arrays

  • Nested Queries: Now respect JSONSerialize query options

  • Connection Pooling:

    • Fixed queries with user/pass override not using pooling

    • Properly override credentials with on-the-fly struct syntax

  • SQLite Error Handling: Database errors now properly handled

List Operations (5+ fixes)

  • listDeleteAt(): Fixed incorrect behavior in both modes

  • List Find BIFs: Fixed unexpected matches in search operations

  • Null Appending: Fixed failures when appending null to list

Number Formatting (5+ fixes)

  • numberFormat():

    • Fixed compatibility with "_.00" mask

    • No longer omits leading zero with _.00 mask

    • Empty string with _.00 mask no longer throws

    • Returns proper value for zero with _.00 mask

  • isNumeric(): isNumeric("true") now returns false (matches ACF/Lucee)

  • val(): Fixed occasional scientific notation in results

  • lsIsCurrency(): Fixed type casting issues

HTTP & Network (10+ fixes)

  • HTTP Component:

    • Fixed basic auth regression (no longer sending proper header)

    • Fixed failures with duplicate response headers

    • Now properly handles responses with both file and path attributes

  • Cookie Component:

    • Fixed expires attribute crashes with createTimeSpan

    • Better date handling for cookie expiration

  • Header Component: Now adds headers instead of replacing (correct CFML behavior)

  • Compression: Fixed gzip decompression issues

File Operations (5+ fixes)

  • fileCopy(): Now respects overwrite parameter

  • File Upload:

    • Files smaller than 10KB now properly stored on disk

    • Fixed allowed extension check when periods are present in filename

    • Fixed regression where content wasn't committed to disk

    • Empty allow argument now treated correctly

  • getFileInfo(): Returns correct type string for directories

  • expandPath(): Fixed using wrong base path when Application.bx in different directory

  • getTempDirectory(): Now contains trailing slash (CFML compat)

Parser Improvements (10+ fixes)

  • Semicolons: After empty statement blocks now properly end statements

  • Whitespace: Allowed in tag closing (/ >)

  • CF Template CFCs: Fixed parsing of template-style component definitions

  • Ternary Operator: Assignment inside ternary now parses correctly

  • continue in switch: Can now use continue inside switch inside for loop

  • Static Function Invocation: Fixed parse error on static method calls

  • CF Transpiler:

    • Now catches variables inside isDefined() args

    • Better handling of CF template CFC structures

CFML Compatibility (15+ fixes)

  • CGI Values: For compatibility, CGI values are now java.lang.String

  • Boolean Comparison: Don't compare numbers to booleans

  • isValid(): Fixed null reference errors

  • isDefined(): Fixed regression returning false on struct keys

  • reMatchNoCase(): Result is now proper array (not array with 2 elements)

  • Array Comparison: Fixed "Can't compare [String] against [Array]" error

  • structSort(): Fixed issues with unmodifiable arrays from keyArray()

  • Object Component:

    • Type default now being set correctly

    • component attribute handled correctly

  • Custom Tags: thisTag scope now behaves like ACF/Lucee

  • Line Numbers: Correct line numbers reported in tag context

Java Interop (5+ fixes)

  • Field Access: Fixed issues accessing public parent package/private class fields

  • Field Setting: Values now properly coerced when setting Java fields

  • putAll(): Fixed ClassCastException when using Map argument

  • Unmodifiable Arrays: Can now map/filter unmodifiable arrays

  • Native Array Printing: println() better handles Java native arrays

XML Operations (3+ fixes)

  • xmlSearch(): Returns correct value for xpath expressions

  • CFDUMP: Fixed breaking when column names contain commas

Async Operations (2+ fixes)

  • asyncRun(): Executor argument now properly detects BoxExecutors

  • Session Scope: Fixed distributed cache persistence when request ends

Application Lifecycle (3+ fixes)

  • Application Shutdown: Can no longer shutdown mid-request

  • Server Start: Added onServerStart support to compat mode

  • Runtime Wait: Mechanism for runtimes to wait until BoxRuntime instance fully started

  • Datasource Loading: Datasources load first, then caches (avoids chicken/egg issues)

  • Datasource Errors: Server now starts even if one datasource has connection issues

Exception Handling (3+ fixes)

  • Custom Tags in Catch: Can now call custom tags from catch blocks

  • Captured Variables: Now available when capture is performed in catch block

  • Variable Declaration: Can now declare variables using BoxExpressionInvocation

Stored Procedures (2+ fixes)

  • Null Attribute: Component now respects "null" attribute

  • Multiple Result Sets: Fixed CFStoredProc returning multiple result sets

Miscellaneous Fixes

  • Bytecode Versioning: Clear BL home classes folder on upgrade

  • Compiler References: Refactored 3 dangling core references to Java Boxpiler

  • variableName Type: Now allows periods in validation

  • Error Messages: Preserve whitespace in default web error page

  • Query Column Keys: Upper case outer struct keys when serializing query (compat)

  • rereplace(): Ignore invalid backreference groups (don't throw)

🔧 Configuration Updates

Compiler Configuration

The experimental compiler setting is now a top-level directive:

{
  "compiler": "asm",
  "runtime": {
    // runtime settings
  }
}

Valid values: "asm" (default), "java", "noop"

JDBC Configuration

Enhanced placeholder support in datasource URLs:

{
  "datasources": {
    "myDB": {
      "driver": "mysql",
      "url": "jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:3306}/${DB_NAME}",
      "username": "${DB_USER}",
      "password": "${DB_PASS}"
    }
  }
}

⚡ Migration Notes

Breaking Changes

None - This release maintains full backward compatibility with 1.7.x

Compatibility Improvements

This release includes extensive CFML compatibility improvements:

Date/Time Handling:

  • Better date parsing with various masks

  • Proper timezone respect in Application settings

  • Null date handling in formatting functions

Query Operations:

  • Connection pooling with credential overrides

  • Better query metadata tracking

  • Oracle-specific improvements

List Operations:

  • Fixed listDeleteAt() behavior

  • Better null handling

Number Formatting:

  • numberFormat() mask compatibility

  • isNumeric() behavior matches ACF/Lucee

HTTP Operations:

  • Basic auth header handling

  • Duplicate header support

  • Cookie expiration handling

CGI Scope:

  • Values are now java.lang.String for compatibility

Comparison Operations:

  • No longer compare numbers to booleans

  • Proper array vs string comparison errors

HTTP Migration: If you're using the old HTTP component or custom HTTP code, consider migrating to the new fluent APIs:

// Old style (component)
<bx:http url="https://api.example.com" method="GET" result="myResult" />

// New style (fluent BIF)
myResult = http( "https://api.example.com" )
    .get()
    .send(); // Returns the result struct directly

// Or with transformation
data = http( "https://api.example.com/users.json" )
    .get()
    .transform( ( result ) => deserializeJSON( result.fileContent ) )
    .send(); // Returns deserialized data

SOAP Integration: If you're integrating with SOAP web services, use the new soap() BIF or traditional createObject("webservice") for automatic WSDL parsing and fluent method invocation:

// New soap() BIF (recommended)
ws = soap( "http://example.com/service.wsdl" )
    .timeout( 60 )
    .withBasicAuth( "user", "pass" );

// Or traditional createObject
ws = createObject( "webservice", "http://example.com/service.wsdl" );

// Invoke methods
result = ws.methodName( arg1, arg2 );

Configuration: Update your boxlang.json to use the new top-level compiler directive if you were using the experimental setting.


🎶 Release Notes

Bugs

BL-1850 this.timezone not respected in Application.bx

BL-1874 jsessionid cookie value set to null - breaks AWS WAF

BL-1884 Compat: GetTempDirectory Does not Contain Trailing Slash

BL-1886 ByteCode Versioning on Upgrade - clear BL home classes folder

BL-1888 DateAdd changes date when added 0 'w'

BL-1889 parseDateTime - Can't cast [Nov-05-2025 8:43am] to a DateTime.

BL-1890 HTTP request fails with exception when server response with duplicate headers

BL-1892 stored proc component not respecting "null" attribute

BL-1896 cfdump breaks when column names have comma

BL-1897 servlet runtime is not using the real page context

BL-1899 QueryFilter returning unexpected rows

BL-1900 sorting an array of numerics errors on decimals

BL-1901 querysclice mishandles offset

BL-1906 calling custom tag from catch block errors

BL-1908 Parser: semicolons after empty statement block don't end the statement

BL-1909 xmlSearch doesn't return correct value for xpath expression

BL-1910 Datasources need to lead first, then caches to avoid chicken and egg issues

BL-1911 When using SQLite with BoxLang, database errors (like creating a table that already exists) are not handled properly.

BL-1912 StructFindKey doesn't seem to return references

BL-1913 Application can shutdown mid request

BL-1914 captured variable not available when capture is performed in catch block

BL-1926 Boxlang server does not start if one datasource has connection issues

BL-1927 reMatchNoCase result is an array with 2 elements

BL-1928 Can't compare [String] against [Array]

BL-1929 Date Casting issues when JVM locale is `de_DE` or `en_DE`

BL-1930 Can't cast [0] to a DateTime

BL-1931 FileUpload fails allowed extension check when periods are present

BL-1932 list / array find BIFs returning unexpected matches

BL-1933 acf/lucee compat -- numberFormat( "", '_.00' ) throws

BL-1934 acf/lucee compat - numberFormat(0, "_.00") returns ".00"

BL-1935 Can't cast [Jul 17, 2017 9:29:40 PM] to a DateTime.

BL-1938 number format omits leading zero with _.00 mask

BL-1939 isDate(0) returns true

BL-1941 isValid - Cannot invoke "java.lang.CharSequence.length()" because "this.text" is null

BL-1942 isDate - can't cast '0000009' to a BigDecimal

BL-1943 SessionScope in distributed cache not persisting when request ends

BL-1946 Dynamic Interop getField() issue when trying to access a public class parent package/private class fields

BL-1947 bad parse (?) on static function invocation

BL-1948 can't use `continue` inside `switch` inside `for`

BL-1949 For CFML compatibility CGI values should be java,lang.string

BL-1950 Nested queries ignore JSONSerialize query options

BL-1951 Don't compare numbers to booleans

BL-1952 lsIsCurrency - can't cast java.lang.Integer to java.lang.String

BL-1956 `timeFormat` can produce strings containing non-ascii whitespace

BL-1958 CF compat: allow whitespace in / > tag closing

BL-1959 Parsing CF template CFC

BL-1960 assingment inside ternary parses wrong

BL-1962 val() sometimes returns scientific notation

BL-1963 array append throws java.lang.UnsupportedOperationException when array originates from struct.keyArray()

BL-1965 values not coerced when setting Java fields

BL-1966 {}.putAll(Map) throws ClassCastException

BL-1967 Can't cast [Jun-30-2010 04:33] to a DateTime

BL-1969 Optimize DateTimeFormatter Usage

BL-1971 Cannot map/filter an unmodifiable array

BL-1972 query with user/pass override doesn't use connection pooling

BL-1973 query with user/pass override doesn't override on-the-fly struct

BL-1976 asyncRun() executor argument was not detecting BoxExecutors directly.

BL-1977 Regression: isDefined returning false on struct key

BL-1978 CF transpiler doesn't catch variables inside isDefined args

BL-1980 CFCookie Expires crashes if using CreateTimeSpan

BL-1981 Object Component - Type Default Not Being Set

BL-1982 Can't cast [Jun-3-2010 04:33] to a DateTime.

BL-1983 Can't cast [11/21/2025 1:05] to a DateTime

BL-1984 isNumeric("true") is true on boxlang, false on lucee/acf

BL-1985 Refactor 3 dangling core references to the Java Boxpiler

BL-1987 CFTag support for thisTag scope behaves differently than ACF/Lucee

BL-1988 You cannot declare a variable using BoxExpressionInvocation

BL-1989 Compat: `format` member function undocumented but supported for DateTime objects

BL-1994 Compat: `component` attribute not handled correctly by Object component

BL-1995 Incorrect line number reported in tag context

BL-1996 header component should add header, not replace

BL-1997 Regression: HTTP Component Basic Auth no longer sending proper header

BL-1998 Compat: Add handling for null dates in formatting methods

New Features

BL-1835 context shutdown listeners

BL-1891 Add mechanism for runtimes to wait until BoxRuntime instance is started

BL-1893 Add onServerStart support to compat module

BL-1895 ServerSideEventConsumer(), SSEConsume() bif to allow from the core to connect and consume events. This is imperative for LLM integrations

BL-1898 ServerSideEventConsumer to allow for any BoxLang app to consume SSE events in a streaming fashion, especially tuned for LLMs

BL-1921 Fluent HTTP Client with http() bif

BL-1922 HTTP Service for managing and controlling http client life-cycles

BL-1923 Ability for our HTTP calls to persist connection and state across executions

BL-1924 HTTP Streaming capabilities for the http components (SSE, Regular Streams)

BL-1970 SOAP Client Consumer

BL-1974 added simpleName to metadata for classes for ease of use

BL-1990 StructFindValue breaks if any key is an array

Improvements

BL-1315 Create a way to load jars dynamically - enhanced DynamicClassLoader with addPaths()

BL-1518 Remove all JavaParser dependencies externally unless you check if it exists

BL-1617 Refactor the experimental compiler setting to a top-level directive in the boxlang.json: compiler

BL-1868 More robust placeholder replacements in JDBC URLs

BL-1887 Rename SSE BIF to ServerSideEvent and add Alias to SSE

BL-1894 Added descriptions to web support bifs/components

BL-1902 Add support for query type of text, map to varchar

BL-1903 Enhance feature audit to find REST classes

BL-1905 Support rowID/generatedKey for Oracle

BL-1918 Make datasource URL placeholder replacements case-insensitive

BL-1919 Faster bx:thread joining

BL-1920 Allow JDBC Drivers to override query column types

BL-1925 variableName type allows periods

BL-1936 Preserve whitespace in error messages in default web Error page

BL-1937 track original JDBC col type and make available in query meta

BL-1940 varchar param doesn't match char field in Oracle driver

BL-1945 Support BLOB and CLOB properly

BL-1957 Compat-- upper case outer struct keys when serializing query

BL-1968 Use background thread to check app timeouts

BL-1975 Micro optimizations to promote speed when creating metadata by using imperative programming

BL-1986 println() better handling of java native arrays

BL-1991 Oracle stored procs support for ref cursors

BL-1992 rereplace() ignore invalid backreference groups

Last updated

Was this helpful?