boxlang-runtime-jsr-223 — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited boxlang-runtime-jsr-223 (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
JSR-223 ("Scripting for the Java Platform") allows Java applications to embed BoxLang as a scripting engine. This enables dynamic business logic, configurable rules, template processing, and runtime extensibility without a full recompile.
<dependency>
<groupId>io.boxlang</groupId>
<artifactId>boxlang</artifactId>
<version>1.10.1</version>
</dependency>dependencies {
implementation 'io.boxlang:boxlang:1.10.1'
}Requirement: Java 21+
import javax.script.*;
// Get BoxLang engine by name
ScriptEngine engine = new ScriptEngineManager().getEngineByName( "BoxLang" );
// Execute BoxLang code
Object result = engine.eval( "return 'Hello from BoxLang!'" );
System.out.println( result ); // Hello from BoxLang!Use Bindings to pass Java objects into the BoxLang execution context:
ScriptEngine engine = new ScriptEngineManager().getEngineByName( "BoxLang" );
Bindings bindings = engine.createBindings();
bindings.put( "name", "Java Developer" );
bindings.put( "items", java.util.Arrays.asList( "Spring", "Maven", "BoxLang" ) );
Object result = engine.eval( """
message = "Hello " & name & "!"
itemCount = items.len()
return {
greeting: message,
totalItems: itemCount,
technologies: items.map( ( item ) => item.uCase() )
}
""", bindings );
System.out.println( result );BoxLang can set values back into the Bindings scope for Java to read:
Bindings bindings = engine.createBindings();
bindings.put( "inputData", myData );
engine.eval( """
processed = inputData.map( ( item ) -> item * 2 )
errorCount = 0
successCount = processed.len()
""", bindings );
// Read values back from the scope
Object processed = bindings.get( "processed" );
int successCount = (int) bindings.get( "successCount" );Embed BoxLang for business rules that non-developers can modify:
ScriptEngine engine = new ScriptEngineManager().getEngineByName( "BoxLang" );
// Load rules from a file, database, or config — not hardcoded Java
String discountRules = Files.readString( Path.of( "rules/discount.bxs" ) );
Bindings ctx = engine.createBindings();
ctx.put( "customer", customerData );
ctx.put( "order", orderData );
Boolean eligible = (Boolean) engine.eval( discountRules, ctx );rules/discount.bxs:
// Business rules — editable without recompiling Java
if ( order.total > 1000 && customer.tier == "GOLD" ) {
return true
}
if ( customer.loyaltyPoints > 5000 ) {
return true
}
return falseUse BoxLang string interpolation as a lightweight template engine:
ScriptEngine engine = new ScriptEngineManager().getEngineByName( "BoxLang" );
String template = Files.readString( Path.of( "templates/email.bxs" ) );
Bindings data = engine.createBindings();
data.put( "firstName", "Alice" );
data.put( "orderNumber", "ORD-12345" );
data.put( "total", 99.99 );
String rendered = (String) engine.eval( template, data );
System.out.println( rendered );templates/email.bxs:
return """
Dear #firstName#,
Your order #orderNumber# totaling $#numberFormat( total, "0.00" )# has been confirmed.
Thank you for your business!
"""ScriptEngineManager creates a new runtime per call. For production use, create the engine once and reuse it:
// Application startup — create engine once
private static final ScriptEngine BOXLANG_ENGINE =
new ScriptEngineManager().getEngineByName( "BoxLang" );
// Per-request — create fresh Bindings but reuse the engine
public Object evaluate( String script, Map<String, Object> vars ) throws ScriptException {
Bindings bindings = BOXLANG_ENGINE.createBindings();
bindings.putAll( vars );
return BOXLANG_ENGINE.eval( script, bindings );
}Control where BoxLang stores its runtime files (classes, modules, config):
// Set BOXLANG_HOME before creating the engine manager
System.setProperty( "boxlang.home", "/opt/myapp/.boxlang" );
ScriptEngine engine = new ScriptEngineManager().getEngineByName( "BoxLang" );Or via environment variable before JVM startup:
export BOXLANG_HOME=/opt/myapp/.boxlang
java -jar myapp.jarModules extend BoxLang with BIFs, components, and capabilities:
// Using system property
System.setProperty( "boxlang.home", "/opt/myapp/.boxlang" );
// Then install modules to /opt/myapp/.boxlang/modules/ via box CLI
// box install bx-mail --boxlang-home=/opt/myapp/.boxlangOr set in boxlang.json in the home directory:
{
"modules": {
"load": [ "bx-mail", "bx-pdf" ]
}
}BoxLang exceptions are wrapped in ScriptException. Unwrap to inspect:
try {
engine.eval( script, bindings );
} catch ( ScriptException e ) {
// e.getCause() may be a BoxLang runtime exception
Throwable cause = e.getCause();
if ( cause != null ) {
System.err.println( "BoxLang error: " + cause.getMessage() );
} else {
System.err.println( "Script error: " + e.getMessage() );
}
}| Class | Purpose |
|---|---|
ScriptEngineManager | Discovers and creates script engines |
ScriptEngine | Executes scripts, manages state |
Bindings | Key-value map for passing data to/from scripts |
ScriptContext | Full context (global + engine-level Bindings) |
Compilable | Compile scripts for repeated execution (if supported) |
Invocable | Call specific functions defined in the engine |
Bindings per execution to prevent state leakageScriptException.getCause() inspectedBOXLANG_HOME set to a writable, isolated directory~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.