BoxLang has an installation-level configuration file that allows developers to adjust various settings from the compiler to default cache providers, runtime-wide data sources, and much more. Depending on which runtime you are using, the configuration file location might change, but the configuration segments remain the same.
Once you startup a runtime, the runtime will find the BOXLANG_HOMEand create the config/boxlang.jsonfile with the defaults that it ships with. You may also change the granular config settings at runtime using the environment or Java properties by prefixing any configuration item with BOXLANG_or boxlang. See below.
If you are running BoxLang within CommandBox, the configuration file will be inside the server directory inside of CommandBox under WEB-INF/boxlang/. You can also run the following command to see the server home directory:
server status property=serverHome
Runtime Home Directory
By default, the BoxLang home directory is a .boxlang/ directory inside your user's home directory. For instance, on a Ubuntu machine, this might be /home/elpete/.boxlang/ if you are executing BoxLang under the elpete user account.
ℹ️ The BoxLang home can be adjusted on startup via a --home flag:
boxlang --home /path/to/boxlang-home
By allowing a custom home directory, you can manage multiple BoxLang runtimes and allow:
custom, per-runtime configuration
a custom set of BoxLang modules
etc
Boxlang.json Reference
Here is the latest reference of the current default boxlang.json file:
Please note that JSON support in BoxLang allows you to use comments inline.
Internal Variables
The following are the internal variable substitutions you can use in any value:
* ${boxlang-home} - The BoxLang home directory
* ${user-home} - The user's home directory
* ${user-dir} - The user's current directory
* ${java-temp} - The java temp directory
BoxLang gives you the ability to override any of the runtime configuration or module settings via environment variables or Java system properties. For example adding an environment variable of boxlang.security.allowedFileOperationExtensions=.exe,.sh would override the disallowed defaults, and allow users to upload and rename files with these extensions ( not a good idea! ).
The variable names can be either snake-cased or dot-delimited. For example BOXLANG_DEBUGMODE=true will work the same as boxlang.debugMode=true to set the entire runtime in to debug mode.
This convention allows you to make granular changes to sub-segments of the configuration without overriding parent items. JSON is also allowed when overriding config settings. For example, if I wanted to set the runtime logging level to trace without putting the runtime in to DebugMode, I could set the environment variable: boxlang.logging.loggers.runtime.level=TRACE or add the JVM arg -Dboxlang.logging.loggers.runtime.level=TRACE
Environment Variable Substitution
BoxLang supports environment variable substitution using the syntax ${env.environment_variable_name:default}. For example, using ${env.MYSQL_HOST:localhost} will result in the value of the MYSQL_HOST environment variable, if found, or fall back to the localhost value if the environment variable is not defined.
Inside your boxlang.json configuration file, you can use this to populate datasource credential secrets:
/**
* BoxLang Configuration File
*
* Here are some of the available variables you can use in this file:
* ${boxlang-home} - The BoxLang home directory
* ${user-home} - The user's home directory
* ${user-dir} - The user's current directory
* ${java-temp} - The java temp directory
* ${env.variablename:defaultValue} - The value of a valid environment variable or the default value. Example: ${env.CFCONFIG_HOME:/etc/cfconfig}
*/
{
// Extensions BoxLang will process as classes
"validClassExtensions": [
"bx",
// Moving to compat at final release
"cfc"
],
// Extensions BoxLang will process as templates.
// This is used by the RunnableLoader
"validTemplateExtensions": [
"bxs",
"bxm",
"bxml",
// Moving to compat at final release
"cfm",
"cfml",
"cfs"
],
// Where all generated classes will be placed
"classGenerationDirectory": "${boxlang-home}/classes",
// This puts the entire runtime in debug mode
// Which will produce lots of debug output and metrics
// Also the debugging error template will be used if turned on
"debugMode": false,
// This enables the class locations cache for the runtime. It's used when resolving class paths
// mostly using mappings, per request mappings, etc.
// We recommend you always enable this setting, unless debugging a very specific issue
"classResolverCache": true,
// This enables the runnable loader's cache on disk for compiled BoxLang classes
// This means that it will load a Boxlang class and never inspect the file again
// Turn this on for production, but off for development so you can see your changes
"trustedCache": false,
// The default timezone for the runtime; defaults to the JVM timezone if empty
// Please use the IANA timezone database values
"timezone": "",
// The default locale for the runtime; defaults to the JVM locale if empty
// Please use the IETF BCP 47 language tag values
"locale": "",
// Enable whitespace compression in output. Only in use by the web runtimes currently.
"whitespaceCompressionEnabled": true,
// By default BoxLang uses high-precision mathematics via BigDecimal operations
// You can turn this off here for all applications
"useHighPrecisionMath": true,
// If true, you can call implicit accessors/mutators on object properties. By default it is enabled
// You can turn it on here for all applications or in the Application.cfc
"invokeImplicitAccessor": true,
// Use Timespan syntax: "days, hours, minutes, seconds"
"applicationTimeout": "0,0,0,0",
// The request timeout for a request in seconds; 0 means no timeout
"requestTimeout": "0,0,0,0",
// The session timeout: 30 minutes
"sessionTimeout": "0,0,30,0",
// Where sessions will be stored by default. This has to be a name of a registered cache
// or the keyword "memory" to indicate our auto-created cache.
// This will apply to ALL applications unless overridden in the Application.cfc
"sessionStorage": "memory",
// A collection of BoxLang mappings, the key is the prefix and the value is the directory
"mappings": {
"/": "${user-dir}"
},
// A collection of BoxLang module directories, they must be absolute paths
"modulesDirectory": [
"${boxlang-home}/modules"
],
// A collection of BoxLang custom tag directories, they must be absolute paths
"customTagsDirectory": [
"${boxlang-home}/customTags"
],
// A collection of directories to lookup box classes in (.bx files), they must be absolute paths
"classPaths": [],
// A collection of directories we will class load all Java *.jar files from
"javaLibraryPaths": [
"${boxlang-home}/lib"
],
// Logging Settings for the runtime
"logging": {
// The location of the log files the runtime will produce
"logsDirectory": "${boxlang-home}/logs",
// The maximum number of days to keep log files before rotation
// Default is 90 days or 3 months
// Set to 0 to never rotate
"maxLogDays": 90,
// The maximum file size for a single log file before rotation
// You can use the following suffixes: KB, MB, GB
// Default is 100MB
"maxFileSize": "100MB",
// The total cap size of all log files before rotation
// You can use the following suffixes: KB, MB, GB
// Default is 5GB
"totalCapSize": "5GB",
// The root logger level
// Valid values are in order of severity: ERROR, WARN, INFO, DEBUG, TRACE, OFF
// If the runtime is in Debug mode, this will be set to DEBUG
"rootLevel": "WARN",
// Default Encoder for file appenders.
// The available options are "text" and "json"
"defaultEncoder": "text",
// Activate the status printer on load to print out the logging configuration
// Turn on to debug LogBack and BoxLang logging configurations
"statusPrinterOnLoad": false,
// A collection of pre-defined loggers and their configurations
"loggers": {
// The runtime main and default log
"runtime": {
// Valid values are in order of severity: ERROR, WARN, INFO, DEBUG, TRACE, OFF
// Leave out if it should inherit from the root logger
"level": "INFO",
// Valid values are: "file", "console",
// Coming soon: "smtp", "socket", "db", "syslog" or "java class name"
// Please note that we only use Rolling File Appenders
"appender": "file",
// Use the defaults from the runtime
"appenderArguments": {},
// The available options are "text" and "json"
"encoder": "text",
// Additive logging: true means that this logger will inherit the appenders from the root logger
// If false, it will only use the appenders defined in this logger
"additive": false
},
// All async operations and facilities will log here.
"async": {
// Valid values are in order of severity: ERROR, WARN, INFO, DEBUG, TRACE, OFF
// Leave out if it should inherit from the root logger
"level": "INFO",
// Valid values are: "file", "console",
// Coming soon: "smtp", "socket", "db", "syslog" or "java class name"
// Please note that we only use Rolling File Appenders
"appender": "file",
// Use the defaults from the runtime
"appenderArguments": {},
// The available options are "text" and "json"
"encoder": "text",
// Additive logging: true means that this logger will inherit the appenders from the root logger
// If false, it will only use the appenders defined in this logger
"additive": false
},
// All cache operations and facilities will log here.
"cache": {
// Valid values are in order of severity: ERROR, WARN, INFO, DEBUG, TRACE, OFF
// Leave out if it should inherit from the root logger
"level": "WARN",
// Valid values are: "file", "console",
// Coming soon: "smtp", "socket", "db", "syslog" or "java class name"
// Please note that we only use Rolling File Appenders
"appender": "file",
// Use the defaults from the runtime
"appenderArguments": {},
// The available options are "text" and "json"
"encoder": "text",
// Additive logging: true means that this logger will inherit the appenders from the root logger
// If false, it will only use the appenders defined in this logger
"additive": false
},
// The datasource log is used by the creation, debugging, and management of datasources
"datasource": {
// Valid values are in order of severity: ERROR, WARN, INFO, DEBUG, TRACE, OFF
// Leave out if it should inherit from the root logger
"level": "WARN",
// Valid values are: "file", "console",
// Coming soon: "smtp", "socket", "db", "syslog" or "java class name"
// Please note that we only use Rolling File Appenders
"appender": "file",
// Use the defaults from the runtime
"appenderArguments": {},
// The available options are "text" and "json"
"encoder": "text",
// Additive logging: true means that this logger will inherit the appenders from the root logger
// If false, it will only use the appenders defined in this logger
"additive": false
},
// The modules log is used by the module service and records all module activity
"modules": {
// Valid values are in order of severity: ERROR, WARN, INFO, DEBUG, TRACE, OFF
// Leave out if it should inherit from the root logger
"level": "INFO",
// Valid values are: "file", "console",
// Coming soon: "smtp", "socket", "db", "syslog" or "java class name"
// Please note that we only use Rolling File Appenders
"appender": "file",
// Use the defaults from the runtime
"appenderArguments": {},
// The available options are "text" and "json"
"encoder": "text",
// Additive logging: true means that this logger will inherit the appenders from the root logger
// If false, it will only use the appenders defined in this logger
"additive": false
},
// All applications will use this logger for any custom logging
"application": {
// Valid values are in order of severity: ERROR, WARN, INFO, DEBUG, TRACE, OFF
// Leave out if it should inherit from the root logger
"level": "WARN",
// Valid values are: "file", "console",
// Coming soon: "smtp", "socket", "db", "syslog" or "java class name"
// Please note that we only use Rolling File Appenders
"appender": "file",
// Use the defaults from the runtime
"appenderArguments": {},
// The available options are "text" and "json"
"encoder": "text",
// Additive logging: true means that this logger will inherit the appenders from the root logger
// If false, it will only use the appenders defined in this logger
"additive": false
},
// All scheduled tasks logging will go here
"scheduler": {
// Valid values are in order of severity: ERROR, WARN, INFO, DEBUG, TRACE, OFF
// Leave out if it should inherit from the root logger
"level": "INFO",
// Valid values are: "file", "console",
// Coming soon: "smtp", "socket", "db", "syslog" or "java class name"
// Please note that we only use Rolling File Appenders
"appender": "file",
// Use the defaults from the runtime
"appenderArguments": {},
// The available options are "text" and "json"
"encoder": "text",
// Additive logging: true means that this logger will inherit the appenders from the root logger
// If false, it will only use the appenders defined in this logger
"additive": false
}
}
},
// This is the experimental features flags.
// Please see the documentation to see which flags are available
"experimental": {
// This choose the compiler to use for the runtime
// Valid values are: "java", "asm"
"compiler": "asm",
// If enabled, it will generate AST JSON data under the project's /grapher/data folder
"ASTCapture": false
},
// Global Executors for the runtime
// These are managed by the AsyncService and registered upon startup
// The name of the executor is the key and the value is a struct of executor settings
// Types are: cached, fixed, fork_join, scheduled, single, virtual, work_stealing
// The `threads` property is the number of threads to use in the executor. The default is 20
// Some executors do not take in a `threads` property
"executors": {
"boxlang-tasks": {
"type": "scheduled",
"threads": 20
},
"cacheservice-tasks": {
"type": "scheduled",
"threads": 20
}
},
// You can assign a global default datasource to be used in the language
"defaultDatasource": "",
// The registered global datasources in the language
// The key is the name of the datasource and the value is a struct of the datasource settings
"datasources": {
// "testDB": {
// "driver": "derby",
// "connectionString": "jdbc:derby:memory:testDB;create=true"
// }
// "testdatasource": {
// "driver": "derby",
// "host": "localhost",
// "port": 3306,
// "database": "test"
// }
},
// The default return format for class invocations via web runtimes
"defaultRemoteMethodReturnFormat": "json",
/**
* Register any named caches here.
* The key is the name of the cache and the value is the cache configuration.
*
* A `provider` property is required and the value is the name of the cache provider or the fully qualified class name.
* The `properties` property is optional and is a struct of properties that are specific to the cache provider.
*/
"caches": {
// The configuration for the BoxLang `default` cache. If empty, we use the defaults
// See the ortus.boxlang.runtime.config.segments.CacheConfig for all the available settings
// This is used by query caching, template caching, and other internal caching.
// You can use the cache() BIF in order to get access to the default cache.
"default": {
"provider": "BoxCacheProvider",
"properties": {
// How many to evict at a time once a policy is triggered
"evictCount": 1,
// The eviction policy to use: Least Recently Used
// Other policies are: LRU, LFU, FIFO, LIFO, RANDOM
"evictionPolicy": "LRU",
// The free memory percentage threshold to trigger eviction
// 0 = disabled, 1-100 = percentage of available free memory in heap
// If the threadhold is reached, the eviction policy is triggered
"freeMemoryPercentageThreshold": 0,
// The maximum number of objects to store in the cache
"maxObjects": 1000,
// The maximum in seconds to keep an object in the cache since it's last access
// So if an object is not accessed in this time or greater, it will be removed from the cache
"defaultLastAccessTimeout": 1800,
// The maximum time in seconds to keep an object in the cache regardless if it's used or not
// A default timeout of 0 = never expire, careful with this setting
"defaultTimeout": 3600,
// The object store to use to store the objects.
// The default is a ConcurrentStore which is a memory sensitive store
"objectStore": "ConcurrentStore",
// The frequency in seconds to check for expired objects and expire them using the policy
// This creates a BoxLang task that runs every X seconds to check for expired objects
"reapFrequency": 120,
// If enabled, the last access timeout will be reset on every access
// This means that the last access timeout will be reset to the defaultLastAccessTimeout on every access
// Usually for session caches or to simulate a session
"resetTimeoutOnAccess": false,
// If enabled, the last access timeout will be used to evict objects from the cache
"useLastAccessTimeouts": true
}
},
// This is the holder of all sessions in a BoxLang runtime.
// The keys are prefixed by application to create separation.
"bxSessions": {
"provider": "BoxCacheProvider",
"properties": {
// How many objects to evict when the cache is full
"evictCount": 1,
// The eviction policy to use: FIFO, LFU, LIFO, LRU, MFU, MRU, Random
"evictionPolicy": "LRU",
// The maximum number of objects the cache can hold
"maxObjects": 100000,
// How long should sessions last for in seconds. Default is 60 minutes.
"defaultTimeout": 3600,
// The object store to use to store the objects.
// The default is a ConcurrentStore which is a thread safe and fast storage.
// Available Stores are: BlackHoleStore, ConcurrentSoftReferenceStore, ConcurrentStore, FileSystemStore, Your own.
"objectStore": "ConcurrentStore",
// The free memory percentage threshold to start evicting objects
// Only use if memory is constricted and you need to relieve cache pressure
// Please note that this only makes sense depending on which object store you use.
"freeMemoryPercentageThreshold": 0,
// The frequency in seconds to check for expired objects and expire them using the policy
// This creates a BoxLang task that runs every X seconds to check for expired objects
// Default is every 2 minutes
"reapFrequency": 120,
// This makes a session extend it's life when accessed. So if a users uses anything or puts anything
// In session, it will re-issue the timeout.
"resetTimeoutOnAccess": true,
// Sessions don't rely on the last access timeouts but on the default timeout only.
"useLastAccessTimeouts": false
}
},
// Stores all dynamic regular expressions used in the runtime
"bxRegex": {
"provider": "BoxCacheProvider",
"properties": {
"evictCount": 1,
"evictionPolicy": "LRU",
"freeMemoryPercentageThreshold": 0,
"maxObjects": 500,
// 30 minutes ifnot used
"defaultLastAccessTimeout": 1800,
// 60 minutes default
"defaultTimeout": 3600,
"objectStore": "ConcurrentSoftReferenceStore",
"reapFrequency": 120,
"resetTimeoutOnAccess": false,
"useLastAccessTimeouts": true
}
}
},
// These are the security settings for the runtime
"security": {
// All regex patterns are case-insensitive
// A list of regex patterns that will match class paths, and if matched, execution will be disallowed
// This applies to import statements, createObject, new, and class creation
// Ex: "disallowedImports": ["java\\.lang\\.(ProcessBuilder|Reflect", "java\\.io\\.(File|FileWriter)"]
"disallowedImports": [],
// A list of BIF names that will be disallowed from execution
// Ex: "disallowedBifs": ["createObject", "systemExecute"]
"disallowedBifs": [],
// A list of Component names that will be disallowed from execution
// Ex: "disallowedComponents": [ "execute", "http" ]
"disallowedComponents": [],
// An explicit whitelist of file extensions that are allowed to be uploaded - overrides any values in the disallowedWriteExtensions
"allowedFileOperationExtensions": [],
// The list of file extensions that are not allowed to be uploaded. Also enforced by file relocation operations ( e.g. copy/move )
"disallowedFileOperationExtensions": [
"bat",
"exe",
"cmd",
"cfm",
"cfc",
"cfs",
"bx",
"bxm",
"bxs",
"sh",
"php",
"pl",
"cgi",
"386",
"dll",
"com",
"torrent",
"js",
"app",
"jar",
"pif",
"vb",
"vbscript",
"wsf",
"asp",
"cer",
"csr",
"jsp",
"drv",
"sys",
"ade",
"adp",
"bas",
"chm",
"cpl",
"crt",
"csh",
"fxp",
"hlp",
"hta",
"inf",
"ins",
"isp",
"jse",
"htaccess",
"htpasswd",
"ksh",
"lnk",
"mdb",
"mde",
"mdt",
"mdw",
"msc",
"msi",
"msp",
"mst",
"ops",
"pcd",
"prg",
"reg",
"scr",
"sct",
"shb",
"shs",
"url",
"vbe",
"vbs",
"wsc",
"wsf",
"wsh"
]
},
/**
* The BoxLang module settings
* The key is the module name and the value is a struct of settings for that specific module
* The `enabled` property is a boolean that determines if the module should be enabled or not. Default is true
* The `settings` property is a struct of settings that are specific to the module and will be override the module settings
*/
"modules": {
// The Compat Module
// "compat": {
// "enabled": true,
// "settings": {
// "isLucee": true,
// "isAdobe": true
// }
// }
}
}