Customize your Runtime Creating your first BoxLang Module.pdf
ortussolutions
9 views
29 slides
May 14, 2025
Slide 1 of 29
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
About This Presentation
Led by Brad Wood
Your runtime. Your way. Endless possibilities! In this session we’ll teach you how to customize your runtime, contribute built-in-functions and tags/components to your BoxLang runtime. Intimidated by Java? Don’t be! We will show you how to create your very first BoxLang runtime...
Led by Brad Wood
Your runtime. Your way. Endless possibilities! In this session we’ll teach you how to customize your runtime, contribute built-in-functions and tags/components to your BoxLang runtime. Intimidated by Java? Don’t be! We will show you how to create your very first BoxLang runtime module without a single line of Java code!
Size: 5.27 MB
Language: en
Added: May 14, 2025
Slides: 29 pages
Slide Content
WELCOME
Into the Box 2025: The Future is Dynamic!
www.intothebox.org
GET STARTED
Creating your first BoxLang Module
Customize your Runtime
Brad Wood
•Lead developer of CommandBox CLI
•BoxLang Framework Architect
•I’ve made 9,722 commits on GitHub since 2011
Senior Software Architect [email protected] @bdw429s
●BoxLang’s entire runtime is modular and extensible
●This was the case from day one of this project
●We have a ModuleService which is very similar to
ColdBox/CommandBox/ContentBox, but at the runtime level
●The BoxLang core allows anything to be dynamically registered
●Modules can be written entirely in Java, in BoxLang, or in a mix of both. You choose!
●Ortus has written dozens of “official” modules
●You can write your own private or public modules
●Publish your modules directly to ForgeBox for the world to use
BoxLang Modules
●BIFs (Built In Functions)
●Components (formerly known as tags)
●Classes
●Interceptors (listening to core BL runtime event announcements)
●Custom Components (AKA Custom Tags)
●Jars
●Configuration
●Caches
●JDBC Drivers
●Custom Contexts/scopes
BoxLang Modules
●Default locations
○boxlang_modules/ folder in the working directory
○modules/ folder inside the BoxLang home folder
●You can configure additional folders in the boxlang.json file
●You can configure additional folders via env variable
Module Locations
●A folder
●A ModuleConfig.bx class
○configure()
■settings
■interceptors
○onLoad()
○onUnload()
●bifs/ folder
●components/ folder
●libs/ folder
Module Structure
The only requirement is the
ModuleConfig.bx
Everything else is optional!
●configure() method
○Runs when module is registered, but before it’s activated. Responsible for
creating settings structure which defines default settings for the module.
The user can override these in their BoxLang config!
●onLoad() method
○Runs when the module activates and can register additional items with
the runtime, or setup anything the module needs
●onUnload() method
○Runs when the module is unloaded (or the runtime shuts down). Clean up
and unregister any custom items.
ModuleConfig.bx
function onLoad() {
boxRuntime.getConfiguration().registerMapping( "/foobar", "C:/foo/bar");
println( "This module is LOADED!" )
}
Module onLoad
ModuleConfig.bx
●Every module gets an automatic class mapping created that points to the
root of the module
●/bxModules/moduleName/
●Customize the mapping name in your ModuleConfig.bx
this.mapping = "waffle"
●You can access files inside the module
fileRead( "/bxModules/myModule/resources/settings.json" )
●You can create classes from inside the module
new bxModules.myModule.models.FooService()
Automatic Mapping
●Each module has a dedicated class loader, pointed at the lib/ folder.
●This is for 3rd party jars, or even custom Java classes you write
●Each module is an “island” so they won’t cloud the system
classloader with potentially different versions of the same library
●There is a namespace registered for Java class paths
new com.foo.JavaClass@myModule()
Module Classloader
There is not a specific convention for custom tags, but since there is a
mapping created that points to the root of the module and custom tags
are searched for in any mapping, you can just place a .bxm or .bxs
folder in the root of your module and it will be usable as a custom
component/tag.
Module Custom Components
●BIFs -> Built In Functions
●First-class headless global functions like now() or fileRead()
●You can OVERWRITE core BIFs. Be careful! With great power comes
great responsibility.
●Add bx class to bifs/ folder
●Name of class is name of BIF
●Needs @BoxBIF annotation
●invoke() method runs it
●BIF arguments are passed along to the invoke() method
Register BIFs
import ortus.boxlang.runtime.types.DateTime;
@BoxBIF
class {
function invoke(){
return new DateTime();
}
}
BIF Example
bifs/Now.bx
●Create one alias for the BIF with
@BoxBIF( "nowButCooler" )
●Create many aliases with
@BoxBIF( [
"nowButCooler",
"now2point0",
"nowBrad"
] )
BIF Aliases
●Register BIF as member method on a type
@BoxMember( "array" )
●If the BIF name starts with the type name, then the
member method removes that text from the name
arrayAppend() becomes just myArr.append()
○Get fancy
@BoxMember( { "string": { "name": "append", "objectArgument": "string" } })
BIF Member Methods
●Components -> used to be called tags
●Components have both a template and a script sytnax
●First-class global like bx:http or bx:mail
●You can OVERWRITE core components. Be careful!
●Add bx class to components/ folder
●Name of class is name of component
●Needs @BoxComponent annotation
●invoke() method runs it
Register Components (tags)
●invoke() arguments
○context - The BoxLang Context
○Struct attributes - The attributes passed by the user
○body - A function that represents the body of the component
○Struct executionState - Data about execution
Component invoke() method