Compat CFML
This module allows your BoxLang engine to simulate an Adobe ColdFusion or Lucee CFML server for seamless migration with zero code changes
Welcome to the BoxLang Compatibility Module For CFML
The BoxLang CFML Compatibility Module (bx-compat-cfml) transforms BoxLang's runtime behavior to match Adobe ColdFusion or Lucee CFML servers, enabling zero-code migration (HOPEFULLY, this is not guaranteed) of existing CFML applications to BoxLang. This comprehensive compatibility layer ensures your legacy CFML applications run identically under BoxLang without modification.
🎯 Purpose
This module bridges the behavioral differences between BoxLang's modern runtime and traditional CFML engines by:
Runtime Behavior Simulation - Mimics null handling, type coercion, and comparison semantics
Server Scope Compatibility - Seeds the
serverscope with engine-specific metadataCFML BIF Compatibility - Provides legacy function signatures and behaviors
Client Scope Management - Emulates Adobe/Lucee client variable storage
JSON Parsing Flexibility - Supports lenient JSON parsing like Lucee
Query Result Compatibility - Matches Adobe/Lucee query null handling
AST Transpiler Settings - Controls how CFML code is transpiled to BoxLang
📦 Installation
If there are any issues, please report them to the BoxLang JIRA or the Module Issues repository.
# For Operating Systems using the Quick Installer
install-bx-module bx-compat-cfml
# Using CommandBox for web servers
box install bx-compat-cfml⚙️ Configuration Settings
The module provides extensive configuration options to control runtime behavior. All settings can be configured via your boxlang.json configuration file or the module's default settings.
Complete Settings Reference
settings = {
// ========================================
// Engine Selection
// ========================================
// Choose your target engine: "adobe" or "lucee"
// This determines which compatibility interceptor loads and how the server scope is populated
engine = "lucee",
// Auto-set based on engine selection (read-only)
isLucee = false,
isAdobe = false,
// ========================================
// Client Scope Management
// ========================================
// Enable Adobe/Lucee client variable management
clientManagement = false,
// Client storage mechanism
// Options: "cache" (uses bxClients cache), or specify your own cache name
// Legacy options "cookie" and "registry" will fallback to cache storage
clientStorage = "cache",
// Default client variable timeout (timespan)
clientTimeout = createTimeSpan( 0, 1, 0, 0 ), // 1 hour
// ========================================
// Null & Type Coercion Behavior
// ========================================
// Mimic CFML behavior where null is treated as undefined
// Set to false for full Java-style null support
nullIsUndefined = true,
// Mimic CF/Lucee 5 behavior where boolean true/false = 1/0 in math operations
// Also affects isNumeric() BIF behavior
// Set to false to match Lucee 6 behavior
booleansAreNumbers = true,
// Auto-cast Java Class instances to strings (calls toString())
castClassesToStrings = true,
// Auto-cast Java Throwable instances to strings (calls toString())
castThrowablesToStrings = true,
// Perform loose date comparison only to instant level (ignores timezone)
// Mimics CFML date comparison behavior
lenientDateComparison = true,
// Treat null and empty string as equal in comparisons
// Matches Adobe/Lucee behavior
nullEqualsEmptyString = true,
// ========================================
// JSON Handling
// ========================================
// Auto-escape JSON control characters during serialization
// WARNING: Enabling this escapes the entire JSON output and impacts performance
jsonEscapeControlCharacters = true,
// Allow lenient JSON parsing (like Lucee)
// Accepts: single quotes, unquoted keys, trailing commas, leading numeric zeroes
// Note: Adobe always uses strict JSON parsing (this setting ignored when engine="adobe")
lenientJSONParsing = true,
// ========================================
// Query Behavior
// ========================================
// Convert query null values to empty strings (when not in full null support mode)
// Simulates Adobe/Lucee query result behavior
queryNullToEmpty = true,
// ========================================
// Struct Casting Behavior
// ========================================
// Allow ANY Java class to be generically cast to struct (uses public fields/getters)
// CF allows even closures to be passed into struct BIFs
// BoxLang normally only uses generic class-to-struct logic for isObject() types
// Set to true for maximum Adobe/Lucee compatibility
extraLooseStructCasting = true,
// ========================================
// CFML to BoxLang Transpiler Settings
// ========================================
transpiler = {
// Convert all keys to uppercase (foo.bar becomes foo.BAR)
// Matches CFML case-insensitive key behavior
upperCaseKeys = true,
// Add output=true attribute to all functions and components
// Matches CFML default output behavior
forceOutputTrue = true,
// Merge JavaDoc-style comments into function/class/property annotations
// Matches CFML hint/documentation behavior
mergeDocsIntoAnnotations = true
},
// ========================================
// Server Lifecycle
// ========================================
// Enable Application.cfc/cfm onServerStart() event interception
serverStartEnabled = true,
// Path to Application.cfc/cfm for server start event
// Can be dot-delimited path using mappings or absolute file path
serverStartPath = ""
};The valid engines are adobe or lucee (default: lucee). All module settings can be overridden via the boxlang.json configuration file.
Example boxlang.json Configuration
{
"modules": {
"compat-cfml": {
"disabled": false,
"settings": {
"engine": "adobe",
"clientManagement": true,
"clientStorage": "cache",
"nullIsUndefined": true,
"booleansAreNumbers": true,
"castClassesToStrings": true,
"castThrowablesToStrings": true,
"lenientDateComparison": true,
"nullEqualsEmptyString": true,
"jsonEscapeControlCharacters": true,
"queryNullToEmpty": true,
"extraLooseStructCasting": true,
"lenientJSONParsing": false,
"transpiler": {
"upperCaseKeys": true,
"forceOutputTrue": true,
"mergeDocsIntoAnnotations": true
},
"serverStartEnabled": true,
"serverStartPath": "/path/to/Application.cfc"
}
}
}
}🎭 Engine-Specific Behavior
Server Scope Simulation
Depending on which engine you select (adobe or lucee), a corresponding interceptor will be loaded that seeds the server scope with engine-specific metadata, ensuring your CFML code sees the expected server information.
Adobe Mode (engine = "adobe"):
Loads
AdobeServerScopeinterceptorPopulates
server.coldfusionstruct with Adobe-specific keysSets
server.coldfusion.productname = "ColdFusion Server"Automatically disables
lenientJSONParsing(Adobe uses strict JSON)
Lucee Mode (engine = "lucee"):
Loads
LuceeServerScopeinterceptorPopulates
server.luceestruct with Lucee-specific keysSets
server.lucee.versionand other Lucee metadataEnables
lenientJSONParsingby default
Additional Interceptors
The module registers several compatibility interceptors regardless of engine selection:
QueryCompat- Ensures query result compatibility (null handling, column types)ClientScopeListener- Manages client variable lifecycle (whenclientManagement = true)ApplicationCompatListener- Application scope compatibilitySessionListener- Session scope compatibilityDateTimeMaskCompat- Date/time formatting mask compatibilityORMApplicationListener- ORM compatibility (if ORM is enabled)RuntimeConfigListener- Runtime configuration compatibility
📚 Contributed Built-In Functions (BIFs)
The compat module registers the following CFML-compatible BIFs globally in the BoxLang runtime:
Cache Management Functions
Client Variable Functions
Metadata & Introspection Functions
Date/Time Functions
Data Conversion Functions
Encryption & Hashing Functions
Formatting Functions
File I/O Functions
Math Functions
Struct Functions
System Functions
🧩 Contributed Components
The module provides CFML-compatible component implementations:
bx:HTTP
Legacy HTTP component matching Adobe/Lucee cfhttp tag behavior
bx:ObjectCache
Client-side object caching component
🪝 Custom Interception Points
The module registers custom interception points for extension:
onClientCreated
Fired when a new client session is created
Client variable management creates a new client
onClientDestroyed
Fired when a client session is destroyed
Client session times out or is explicitly cleared
onLegacyDateFormatRequest
Fired when legacy date format is requested
Date formatting functions use CFML mask patterns
🗂️ CFIDE Mappings
The module automatically registers the /CFIDE mapping pointing to {moduleRoot}/CFIDE, providing compatibility interfaces for:
ORM -
CFIDE/orm/IEventHandler.cfc,CFIDE/orm/INamingStrategy.cfcScheduler -
CFIDE/scheduler/ITaskEventHandler.cfc
These interfaces allow CFML applications that extend Adobe/Lucee framework interfaces to run without modification.
🔄 Client Scope Management
When clientManagement = true, the module provides full CFML-compatible client variable storage:
Client Cache Configuration
The module automatically creates a bxClients cache with the following default settings:
{
evictCount: 1,
evictionPolicy: "LRU",
freeMemoryPercentageThreshold: 0,
maxObjects: 100000,
defaultLastAccessTimeout: 3600,
defaultTimeout: 3600,
objectStore: "ConcurrentStore",
reapFrequency: 120,
resetTimeoutOnAccess: true,
useLastAccessTimeouts: false
}Client Storage Options
cache(default) - Uses thebxClientscache for storagecookie- Falls back to cache storage (cookie storage deprecated)registry- Falls back to cache storage (registry storage deprecated)Custom cache name - Specify your own cache name (must exist)
Client Context
When client management is enabled, the module provides a ClientBoxContext and ClientScope that mimics Adobe/Lucee client variable behavior, including automatic persistence and retrieval.
🚀 Migration Strategy
Zero-Code Migration Path
Install the module:
install-bx-module bx-compat-cfmlConfigure engine: Set
engine = "adobe"orengine = "lucee"inboxlang.jsonEnable features: Configure client management, null handling, and other compatibility flags
Test thoroughly: Run your application test suite to verify compatibility
Optimize gradually: Once stable, progressively disable compatibility flags to adopt BoxLang's modern features
Please note that this is not guaranteed. Every codebase is different.
Recommended Initial Settings (Maximum Compatibility)
{
"modules": {
"compat-cfml": {
"settings": {
"engine": "lucee",
"clientManagement": true,
"nullIsUndefined": true,
"booleansAreNumbers": true,
"castClassesToStrings": true,
"castThrowablesToStrings": true,
"lenientDateComparison": true,
"nullEqualsEmptyString": true,
"jsonEscapeControlCharacters": true,
"queryNullToEmpty": true,
"extraLooseStructCasting": true,
"lenientJSONParsing": true
}
}
}
}Progressive Modernization
Once your application runs successfully, you can progressively adopt BoxLang's modern features by disabling compatibility flags:
Null Support: Set
nullIsUndefined = falsefor proper null handlingType Safety: Set
booleansAreNumbers = falsefor type-safe boolean operationsJSON Standards: Set
lenientJSONParsing = falsefor strict JSON parsingQuery Nulls: Set
queryNullToEmpty = falsefor proper null support in queries
📖 Resources
Documentation & Support
BoxLang Docs: https://boxlang.ortusbooks.com
CFDocs Reference: https://cfdocs.org
GitHub Repository: https://github.com/ortus-boxlang/bx-compat-cfml
Report Issues: BoxLang JIRA | Module Issues
Community: BoxLang Slack | BoxLang Forums
📝 Version History & Changelog
Visit the GitHub repository releases for detailed version history and changelog.
Last updated
Was this helpful?
