JavaScript engine implementation that enables JavaScript execution within Java applications with full ECMAScript support and Java-JavaScript interoperability.
—
Core JavaScript execution engine providing context management, script compilation, evaluation, and execution control. Supports both interpreted and compiled modes with comprehensive configuration options.
The Context class represents the runtime environment for JavaScript execution and must be associated with each thread that runs JavaScript code.
/**
* Associates a Context instance with the current thread
* @return Context instance for this thread
*/
public static Context enter();
/**
* Removes the Context association from the current thread
* Must be called in finally block to prevent memory leaks
*/
public static void exit();
/**
* Gets the Context associated with the current thread
* @return Current Context or null if no Context is active
*/
public static Context getCurrentContext();
/**
* Implements Closeable for try-with-resources pattern
* Automatically calls exit() when closed
*/
public void close();Usage Examples:
// Manual Context management
Context cx = Context.enter();
try {
// JavaScript execution code here
} finally {
Context.exit();
}
// Try-with-resources (Rhino 1.7.8+)
try (Context cx = Context.enter()) {
// JavaScript execution code here
// exit() is called automatically
}ContextFactory provides thread-safe Context creation and configuration, recommended over direct Context instantiation.
/**
* Context factory for creating and configuring Context instances
*/
public class ContextFactory {
/**
* Gets the global ContextFactory instance
* @return Global ContextFactory
*/
public static ContextFactory getGlobal();
/**
* Creates and enters a new Context for current thread
* @return New Context instance
*/
public Context enterContext();
/**
* Enters an existing Context for current thread
* @param cx Context to enter, or null to create new
* @return The entered Context
*/
public Context enterContext(Context cx);
/**
* Creates a new Context without entering it
* @return New Context instance
*/
public Context makeContext();
/**
* Executes ContextAction with proper Context lifecycle
* @param action Action to execute with Context
* @return Result from action
*/
public <T> T call(ContextAction<T> action);
}
/**
* Interface for code that requires Context access
*/
public interface ContextAction<T> {
/**
* Executes with the provided Context
* @param cx Context for JavaScript execution
* @return Action result
*/
T run(Context cx);
}Usage Examples:
// Using ContextFactory.call() (recommended)
Object result = ContextFactory.getGlobal().call(cx -> {
Scriptable scope = cx.initStandardObjects();
return cx.evaluateString(scope, "Math.PI * 2", "calc", 1, null);
});
// Manual ContextFactory usage
ContextFactory factory = ContextFactory.getGlobal();
Context cx = factory.enterContext();
try {
// JavaScript execution
} finally {
Context.exit();
}Scopes define the global object and available JavaScript built-in objects for script execution.
/**
* Initializes standard JavaScript objects (Object, Array, Function, etc.)
* @return Scriptable scope with all standard objects
*/
public ScriptableObject initStandardObjects();
/**
* Initializes standard objects with specified scope object
* @param scope Scope object to initialize
* @return The initialized scope
*/
public Scriptable initStandardObjects(ScriptableObject scope);
/**
* Initializes safe standard objects without Java class access
* Prevents access to Java packages and classes from JavaScript
* @return Safe Scriptable scope
*/
public ScriptableObject initSafeStandardObjects();
/**
* Initializes safe standard objects with specified scope
* @param scope Scope object to initialize safely
* @return The initialized safe scope
*/
public Scriptable initSafeStandardObjects(ScriptableObject scope);Usage Examples:
// Standard scope with Java access
Scriptable scope = cx.initStandardObjects();
// Safe scope without Java access (recommended for sandboxing)
Scriptable safeScope = cx.initSafeStandardObjects();
// Custom scope object
ScriptableObject myScope = new MyCustomScope();
cx.initStandardObjects(myScope);Direct evaluation of JavaScript source code without pre-compilation.
/**
* Evaluates JavaScript source string
* @param scope Scope for variable resolution
* @param source JavaScript source code
* @param sourceName Name for debugging and error reporting
* @param lineno Starting line number
* @param securityDomain Security domain for access control
* @return Evaluation result
*/
public Object evaluateString(Scriptable scope, String source, String sourceName, int lineno, Object securityDomain);
/**
* Evaluates JavaScript from Reader (file, stream, etc.)
* @param scope Scope for variable resolution
* @param in Reader containing JavaScript source
* @param sourceName Name for debugging and error reporting
* @param lineno Starting line number
* @param securityDomain Security domain for access control
* @return Evaluation result
*/
public Object evaluateReader(Scriptable scope, Reader in, String sourceName, int lineno, Object securityDomain);Usage Examples:
// Simple expression evaluation
Object result = cx.evaluateString(scope, "2 + 3", "expression", 1, null);
System.out.println(Context.toString(result)); // "5"
// Multi-line script evaluation
String script = """
var x = 10;
var y = 20;
x + y;
""";
Object sum = cx.evaluateString(scope, script, "calculation.js", 1, null);
// File evaluation
try (FileReader reader = new FileReader("script.js")) {
Object result = cx.evaluateReader(scope, reader, "script.js", 1, null);
}Pre-compilation of JavaScript for better performance when executing repeatedly.
/**
* Compiles JavaScript source string into executable Script
* @param source JavaScript source code
* @param sourceName Name for debugging and error reporting
* @param lineno Starting line number
* @param securityDomain Security domain for access control
* @return Compiled Script object
*/
public Script compileString(String source, String sourceName, int lineno, Object securityDomain);
/**
* Compiles JavaScript from Reader into executable Script
* @param in Reader containing JavaScript source
* @param sourceName Name for debugging and error reporting
* @param lineno Starting line number
* @param securityDomain Security domain for access control
* @return Compiled Script object
*/
public Script compileReader(Reader in, String sourceName, int lineno, Object securityDomain);
/**
* Compiles JavaScript function
* @param scope Scope for compilation
* @param source Function source code
* @param sourceName Name for debugging
* @param lineno Starting line number
* @param securityDomain Security domain
* @return Compiled Function object
*/
public Function compileFunction(Scriptable scope, String source, String sourceName, int lineno, Object securityDomain);Usage Examples:
// Compile once, execute multiple times
Script compiled = cx.compileString("Math.random() * 100", "random.js", 1, null);
// Execute compiled script multiple times
for (int i = 0; i < 10; i++) {
Object result = compiled.exec(cx, scope);
System.out.println("Random: " + Context.toString(result));
}
// Compile and cache functions
Function factorial = cx.compileFunction(scope,
"function factorial(n) { return n <= 1 ? 1 : n * factorial(n-1); }",
"factorial.js", 1, null);
// Call compiled function
Object[] args = {5};
Object result = factorial.call(cx, scope, scope, args);The Script interface represents compiled JavaScript code ready for execution.
/**
* Interface for compiled JavaScript code
*/
public interface Script {
/**
* Executes the compiled script
* @param cx Context for execution
* @param scope Scope for variable resolution
* @return Execution result
*/
Object exec(Context cx, Scriptable scope);
}Configuration options for controlling JavaScript execution behavior.
/**
* Gets the JavaScript language version for this Context
* @return Language version constant
*/
public int getLanguageVersion();
/**
* Sets the JavaScript language version
* @param version Version constant (VERSION_DEFAULT, VERSION_ES6, etc.)
*/
public void setLanguageVersion(int version);
/**
* Gets the error reporter for compilation and runtime errors
* @return Current ErrorReporter
*/
public ErrorReporter getErrorReporter();
/**
* Sets the error reporter for compilation and runtime errors
* @param reporter ErrorReporter implementation
* @return Previous ErrorReporter
*/
public ErrorReporter setErrorReporter(ErrorReporter reporter);
/**
* Checks if debug information generation is enabled
* @return true if debug info is generated
*/
public boolean isGeneratingDebug();
/**
* Controls debug information generation
* @param generatingDebug true to generate debug info
*/
public void setGeneratingDebug(boolean generatingDebug);
/**
* Checks if source information is preserved in compiled code
* @return true if source is preserved
*/
public boolean isGeneratingSource();
/**
* Controls source information preservation
* @param generatingSource true to preserve source
*/
public void setGeneratingSource(boolean generatingSource);
/**
* Checks if interpreter mode is enabled (vs compiled mode)
* @return true if using interpreter
*/
public boolean isInterpretedMode();
/**
* Controls execution mode
* @param interpretedMode true for interpreter, false for compiler
*/
public void setInterpretedMode(boolean interpretedMode);// Language version constants for setLanguageVersion()
public static final int VERSION_DEFAULT = 0; // Use implementation default
public static final int VERSION_1_0 = 100; // JavaScript 1.0
public static final int VERSION_1_1 = 110; // JavaScript 1.1
public static final int VERSION_1_2 = 120; // JavaScript 1.2
public static final int VERSION_1_3 = 130; // JavaScript 1.3
public static final int VERSION_1_4 = 140; // JavaScript 1.4
public static final int VERSION_1_5 = 150; // JavaScript 1.5
public static final int VERSION_1_6 = 160; // JavaScript 1.6
public static final int VERSION_1_7 = 170; // JavaScript 1.7
public static final int VERSION_1_8 = 180; // JavaScript 1.8
public static final int VERSION_ES6 = 200; // ES6/ES2015 (default)
public static final int VERSION_ECMASCRIPT = 250; // Latest ECMAScriptUsage Examples:
// Configure Context for ES6 features
cx.setLanguageVersion(Context.VERSION_ES6);
// Enable debug information for debugging
cx.setGeneratingDebug(true);
cx.setGeneratingSource(true);
// Use interpreter mode for better debugging
cx.setInterpretedMode(true);
// Set custom error reporter
cx.setErrorReporter(new MyErrorReporter());Creating JavaScript objects and arrays from Java code.
/**
* Creates a new JavaScript Object
* @param scope Scope for prototype chain
* @return New empty Object
*/
public Scriptable newObject(Scriptable scope);
/**
* Creates a new JavaScript Object using specified constructor
* @param scope Scope for resolution
* @param constructorName Constructor function name
* @return New object instance
*/
public Scriptable newObject(Scriptable scope, String constructorName);
/**
* Creates a new JavaScript Array with specified length
* @param scope Scope for prototype chain
* @param length Initial array length
* @return New Array object
*/
public Scriptable newArray(Scriptable scope, int length);
/**
* Creates a new JavaScript Array from Java array
* @param scope Scope for prototype chain
* @param elements Initial array elements
* @return New Array object with elements
*/
public Scriptable newArray(Scriptable scope, Object[] elements);Usage Examples:
// Create empty JavaScript objects
Scriptable obj = cx.newObject(scope);
Scriptable arr = cx.newArray(scope, 0);
// Create Date object
Scriptable date = cx.newObject(scope, "Date");
// Create Array with initial elements
Object[] elements = {"hello", "world", 42};
Scriptable array = cx.newArray(scope, elements);
// Set properties on created objects
obj.put("name", obj, "example");
obj.put("value", obj, 123);Configuration for JavaScript compilation process.
/**
* Configuration for JavaScript compilation
*/
public class CompilerEnvirons {
/**
* Initialize from Context settings
* @param cx Context to copy settings from
*/
public void initFromContext(Context cx);
/**
* Check if source preservation is enabled
* @return true if generating source
*/
public boolean isGeneratingSource();
/**
* Control source preservation in compiled code
* @param generatingSource true to preserve source
*/
public void setGeneratingSource(boolean generatingSource);
/**
* Get language version for compilation
* @return Language version constant
*/
public int getLanguageVersion();
/**
* Set language version for compilation
* @param languageVersion Version constant
*/
public void setLanguageVersion(int languageVersion);
}Direct access to JavaScript parsing for AST manipulation.
/**
* JavaScript parser for creating Abstract Syntax Trees
*/
public class Parser {
/**
* Parse JavaScript source into AST
* @param sourceString JavaScript source code
* @param sourceName Source name for error reporting
* @param lineno Starting line number
* @return AST root node
*/
public AstRoot parse(String sourceString, String sourceName, int lineno);
/**
* Parse JavaScript from Reader into AST
* @param sourceReader Reader with JavaScript source
* @param sourceName Source name for error reporting
* @param lineno Starting line number
* @return AST root node
*/
public AstRoot parse(Reader sourceReader, String sourceName, int lineno);
}Usage Examples:
// Parse JavaScript into AST for analysis
Parser parser = new Parser();
CompilerEnvirons env = new CompilerEnvirons();
env.initFromContext(cx);
AstRoot ast = parser.parse("function test() { return 42; }", "test.js", 1);
// Analyze or modify AST...Install with Tessl CLI
npx tessl i tessl/maven-org-mozilla--rhino