BoxLang Dynamic JVM Language v1.10.0 Released


BoxLang 1.10.0 marks a significant milestone in modern JVM programming, delivering powerful functional programming capabilities, elegant syntax improvements, and enterprise-grade distributed locking. This release represents our continued commitment to modernizing dynamic programming for the JVM while also offering a path forward for CFML applications that want to modernize.

The Evolution of Array Programming

Modern application development demands expressive, efficient collection operations. BoxLang 1.10.0 answers this call with nine new array methods that bring functional programming patterns to the forefront of JVM development.

Intelligent Data Chunking

Pagination, batch processing, and UI rendering often require splitting large datasets into manageable pieces. The new chunk() method provides an elegant solution:

items = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
pages = items.chunk( 3 )
// Result: [ [1,2,3], [4,5,6], [7,8,9], [10] ]

// Production example: API pagination
products = productService.getAllProducts()
productPages = products.chunk( 20 )
productPages.each( ( page, index ) => {
    println( "Page #index# contains #page.len()# products" )
} )

Safe Element Access with Defaults

Null-checking boilerplate disappears with findFirst() and first(), which support default values for safer element access:

users = [
    { name: "Alice", role: "user" },
    { name: "Bob", role: "admin" },
    { name: "Charlie", role: "user" }
]

// Eliminate null checks with default fallbacks
admin = users.findFirst( 
    ( u ) => u.role == "admin",
    { name: "Guest", role: "guest" }
)

// Safe configuration access
settings = configArray.first( { theme: "default", locale: "en" } )

Data Aggregation and Grouping

The groupBy() method transforms flat arrays into organized structures using property keys or custom categorization logic:

// Property-based grouping
transactions = [
    { id: 1, category: "food", amount: 45.20 },
    { id: 2, category: "transport", amount: 12.50 },
    { id: 3, category: "food", amount: 28.75 }
]

byCategory = transactions.groupBy( "category" )
// Result: {
//   food: [ {...}, {...} ],
//   transport: [ {...} ]
// }

// Custom categorization logic
bySizeCategory = transactions.groupBy( ( t ) => {
    return t.amount > 100 ? "large" : t.amount > 50 ? "medium" : "small"
} )

Controlled Nested Structure Flattening

The flatten() method provides precise control over how deeply to flatten nested arrays:

nested = [ [1, [2, 3]], [4, [5, [6]]] ]

nested.flatten()      // [1, 2, 3, 4, 5, 6] - complete flattening
nested.flatten( 1 )   // [1, [2, 3], 4, [5, [6]]] - single level
nested.flatten( 2 )   // [1, 2, 3, 4, 5, [6]] - two levels

// Real-world application: API response processing
apiResults = [
    { items: [ {id: 1}, {id: 2} ] },
    { items: [ {id: 3}, {id: 4} ] }
]
allItems = apiResults.map( ( r ) => r.items ).flatten()

Efficient Map-Flatten Operations

flatMap() combines mapping and flattening in a single, efficient operation—essential for processing nested data structures:

orders = [
    { orderId: 1, items: [ "A", "B" ] },
    { orderId: 2, items: [ "C", "D", "E" ] }
]

// Extract and flatten in one operation
allItems = orders.flatMap( ( order ) => order.items )
// Result: [ "A", "B", "C", "D", "E" ]

// Replaces the verbose alternative:
allItems = orders.map( ( order ) => order.items ).flatten()

Expressive Filter Inversion

The reject() method provides the logical inverse of filter(), improving code readability for exclusion scenarios:

products = [
    { name: "Laptop", inStock: true },
    { name: "Mouse", inStock: false },
    { name: "Keyboard", inStock: true }
]

// Clearer intent with reject
outOfStock = products.reject( ( p ) => p.inStock )

// Compare to filter with negation
outOfStock = products.filter( ( p ) => !p.inStock )

Matrix Transformation

The transpose() method converts rows to columns in two-dimensional arrays, enabling matrix operations and data reorganization:

matrix = [
    [ 1, 2, 3 ],
    [ 4, 5, 6 ]
]

transposed = matrix.transpose()
// Result: [ [1, 4], [2, 5], [3, 6] ]

// Practical application: reorganizing tabular data
salesData = [
    [ "Q1", 1000, 1200, 900 ],
    [ "Q2", 1100, 1300, 950 ]
]
byMonth = salesData.transpose()
// Data now organized by columns instead of rows

Type-Aware Duplicate Removal

The unique() method removes duplicate values with optional type-aware comparison:

numbers = [ 1, 2, 2, 3, 1, 4, 3 ]
numbers.unique()  // [ 1, 2, 3, 4 ]

// Type-aware uniqueness
mixed = [ 1, "1", 2, "2", 1 ]
mixed.unique()        // [ 1, "1", 2, "2" ] - type-sensitive
mixed.unique( "any" ) // [ 1, 2 ] - type-insensitive

Element-Wise Array Combination

The zip() method combines multiple arrays element-by-element, perfect for correlating related datasets:

names = [ "Alice", "Bob", "Charlie" ]
ages = [ 25, 30, 35 ]
cities = [ "NYC", "LA", "Chicago" ]

combined = names.zip( ages, cities )
// Result: [
//   [ "Alice", 25, "NYC" ],
//   [ "Bob", 30, "LA" ],
//   [ "Charlie", 35, "Chicago" ]
// ]

// Practical use: combining headers with values
headers = [ "Name", "Email", "Role" ]
values = [ "Alice", "alice@example.com", "Admin" ]
record = headers.zip( values )

Modern Loop Syntax

BoxLang 1.10.0 introduces destructuring syntax for for loops, eliminating verbose iteration patterns while improving code clarity:

// Struct iteration with automatic key-value extraction
userData = {
    name: "Alice",
    email: "alice@example.com",
    role: "admin"
}

for ( key, value in userData ) {
    println( "#key#: #value#" )
}

// Array iteration with item and index
colors = [ "red", "green", "blue" ]
for ( color, index in colors ) {
    println( "Color #index#: #color#" )
}

// Query row processing
for ( row, rowNumber in getUserQuery() ) {
    println( "Processing user #row.name# (row #rowNumber#)" )
}

This elegant syntax replaces verbose callback patterns:

// Previous verbose approach
userData.each( ( key, value ) => {
    println( "#key#: #value#" )
} )

// New streamlined syntax
for ( key, value in userData ) {
    println( "#key#: #value#" )
}

Enterprise-Grade Distributed Locking

In clustered environments, coordinating critical sections across multiple servers traditionally requires external systems like ZooKeeper or database-based locking. BoxLang 1.10.0 integrates distributed locking directly into the lock component through cache providers implementing the ILockableCacheProvider interface.

// Distributed lock protecting cluster-wide critical sections
lock( name="processPayment", cache="redisCache", timeout=30 ) {
    // Protected across all servers in the cluster
    payment = paymentGateway.charge( orderId )
    updateInventory( orderId )
    sendConfirmationEmail( orderId )
}

// Traditional local locks remain available
lock( name="updateLocalCache", type="exclusive", timeout=10 ) {
    localCache.update( key, value )
}

Implementation Requirements: Distributed locking requires cache providers implementing ILockableCacheProvider. Compatible implementations include:

  • bx-redis – Redis-backed distributed locking
  • bx-couchbase – Couchbase distributed locks
  • Custom cache providers implementing the locking interface

Standard BoxLang caches do not support distributed locking by default.

Dynamic Module Management

Runtime module management capabilities enable sophisticated plugin architectures and dynamic extension systems:

moduleService = getModuleService()

// Dynamic module loading
moduleService.loadModule( expandPath( "/plugins/customAuth" ) )

// Batch module loading from directories
moduleService.loadModules( expandPath( "/extensions" ) )

// Module introspection
if ( moduleService.hasModule( "customAuth" ) ) {
    settings = moduleService.getModuleSettings( "customAuth" )
    println( "Custom authentication enabled: #settings.enabled#" )
}

These capabilities support:

  • Dynamic plugin systems – Load user-installed plugins at runtime
  • Feature management – Enable/disable modules based on configuration
  • Java integration – Allow Java applications to extend BoxLang functionality dynamically

Performance Engineering

Compilation and Runtime Optimizations

BoxLang 1.10.0 delivers substantial performance improvements through targeted optimizations:

Fully-Qualified Name Resolution – Significant enhancements to FQN resolution reduce class loading and component instantiation overhead. Applications with heavy component usage benefit from improved startup times and runtime performance.

ASM Compilation Efficiency – The ASM compiler now handles large methods containing try/catch blocks more efficiently through improved method splitting algorithms. This reduces bytecode size and accelerates compilation for complex business logic.

Streaming Binary Responses – The content component now employs chunked transfer encoding for binary responses rather than buffering entire responses in memory. This optimization reduces memory pressure and improves performance for large file downloads, PDF generation, and image serving:

// Efficient streaming of large PDFs without memory buffering
content( type="application/pdf" ) {
    writeOutput( generateLargePDF() ) // Automatically streams in chunks
}

Enhanced Developer Experience

Application Warmup

The MiniServer runtime now supports warmup URLs for pre-initializing applications before serving production traffic:

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

Warmup requests execute sequentially during server startup, ensuring complete application initialization:

  • Cache population
  • Database connection establishment
  • Critical resource initialization
  • Full application readiness before accepting requests

Runtime Introspection

New server scope variables facilitate debugging and runtime identification:

// Java process identification
println( "Running on PID: #server.java.pid#" )

// Active compiler identification
println( "Using compiler: #server.boxlang.compiler#" )

These variables prove invaluable for:

  • Container deployments – Process identification in Kubernetes/Docker environments
  • Performance profiling – Connecting profiling tools to the correct JVM
  • Debugging – Understanding active compilation strategies

Module Binary Infrastructure

BoxLang now provisions a bin/ directory in the BoxLang home, preparing for future CommandBox integration where modules can provide CLI commands and executables:

~/.boxlang/
  └── bin/
      ├── module-cli-tool
      └── custom-command

Containerized JSR-223 Configuration

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

# Environment variable configuration
export BOX_JSR223_TIMEOUT=30000
export BOX_JSR223_ENABLE_LOGGING=true

# System property configuration
java -Dboxlang.jsr223.timeout=30000 \
     -Dboxlang.jsr223.enableLogging=true \
     -jar app.jar

Type System and Language Enhancements

Numeric Type Handling

  • Consistent Casting – General numeric casting now truncates by default, providing consistent behavior across integer conversions
  • Collection Support – The len() function now operates on java.util.Set collections
  • Type ExpansionformatBaseN() correctly handles java.lang.Long types

Cache Hierarchy Management

Cache retrieval now properly respects context cache hierarchies:

// Application-scoped cache takes precedence over global cache
cache( "userSessions" )  // Searches application cache first, then global

// Explicit cache provider targeting
cacheGet( "key", "redisCache" )  // Direct provider access

This ensures application-level cache isolation while maintaining fallback mechanisms to global caches.

Temporal Type Improvements

  • New date format support: "January, 05 2026 17:39:13 -0600"
  • Resolved date equality issues in compatibility mode with different timezones
  • Fixed incorrect false to DateTime object casting in compatibility mode

Query Component Evolution

// Array-based column specification
query = queryNew( [ "id", "name", "email" ] )

Quality Assurance and Bug Resolution

BoxLang 1.10.0 addresses numerous issues across compilation, class systems, collections, file operations, networking, and compatibility modes:

Compilation and ASM

  • Comprehensive rework of large method splitting in ASM compiler
  • Resolution of closure compilation failures inside ternary expressions
  • Elimination of double transpilation in string replace operations with nocase flag
  • Parser fixes for text operators between interpolated variables

Class and Component Architecture

  • Correction of three-level inheritance losing variables scope
  • Resolution of pseudo constructor errors with getClassMetadata()
  • Addition of missing metadata annotations on abstract UDFs
  • Interface implementation validation improvements
  • Correct template references for injected UDFs
  • Thread-safe class reference maintenance for UDF calls

Collection and Struct Operations

  • Proper integer key handling in struct assignments
  • Resolution of string hash collision issues

File System Operations

  • Correct member method scoping on java.io.File instances
  • Preservation of trailing slashes in getCanonicalPath()
  • Proper trailing slash handling in directoryCopy()
  • Compatibility mode overwrite behavior alignment

Network and HTTP

  • BigDecimal to Integer casting resolution in HTTP timeout handling
  • Empty string proxy server handling
  • Duplicate cookie prevention with path variations

Compatibility Mode

  • urlEncodedFormat() alignment with Lucee/ACF
  • Date equality regression fixes with timezone handling
  • Context cache hierarchy usage in compatibility BIFs
  • Optional timeout attribute in Lucee compatibility mode
  • Optional variable attribute in execute component
  • Duplicate UDF declaration support in CF source files

Looking Forward

BoxLang 1.10.0 represents our ongoing commitment to modernizing dynamic JVM programming while respecting the investments organizations have made in their CFML codebases. This release balances innovation with compatibility, delivering powerful new capabilities without disrupting existing applications.

The functional array methods, elegant loop syntax, and distributed locking capabilities position BoxLang as a modern, enterprise-ready platform for JVM development. Combined with our performance optimizations and enhanced developer tooling, BoxLang continues to evolve as a compelling choice for teams seeking the flexibility of dynamic programming with the performance and ecosystem of the JVM.

Resources

BoxLang Platform:

Documentation and Community:


About the Author

Luis Majano is CEO and Chief Software Architect at Ortus Solutions, where he leads the development of BoxLang and the broader enterprise tooling ecosystem. He created the ColdBox framework in 2006 and has spent nearly two decades building professional open source solutions for the JVM. Ortus Solutions operates as a Christian-based company with 40+ professionals and maintains 350+ open-source libraries.

About BoxLang

BoxLang is a modern, dynamic JVM programming language designed for enterprise application development. It provides 100% Java interoperability, CFML compatibility, and supports multi-runtime deployment across operating systems, web servers, serverless platforms, and WebAssembly. BoxLang is developed and maintained by Ortus Solutions without venture capital funding, following professional open-source principles.

Total
0
Shares
Previous Post

Bridging Creativity and Code: Generative AI Video with Java and RunwayML

Related Posts
Java turns 30 in 2025

30 Years of Java, 25 Years of Enterprise Java

Over the last three decades, technology has been evolving at a breakneck pace, with innovations constantly redefining every aspect of application development. In such a fast-moving and dynamic landscape, few technologies stand the test of time, especially in computer science. Yet, Java has done just that. As we celebrate 30 years of Java and 25 years of enterprise Java, it’s clear that these solutions have not only endured but thrived—adapting, advancing and proving their lasting value to software engineers worldwide.
Steve Millidge
Read More