Guide to Using JavascriptService
Updated at 1781769760000JavascriptService is the bridge between JavaScript code and Java beans in EzyPlatform. When a script is passed in, the system does not treat it as plain text. Instead, it creates a Mozilla Rhino runtime scope, injects the required objects such as parameters, properties, console, logger, beanContext, the getBean(...) function, and any pre-included beans, then executes the script.A key update is that
JavascriptService no longer only supports running a script and returning a string. It now also supports the JavascriptFunction mechanism, which allows callers to customize how a script is executed and how its result is converted. In particular, ObjectResultJavascriptFunction allows JavaScript to return an object, array, number, boolean, or string as the corresponding Java object.General architecture
flowchart LR
A["JavaScript source code"] --> B["JavascriptService.execute"]
B --> C["Create Rhino Context"]
C --> D["Create JavaScript scope"]
D --> E["Inject parameters"]
D --> F["Inject properties"]
D --> G["Inject console and logger"]
D --> H["Inject beanContext"]
D --> I["Inject getBean(name)"]
D --> J["Inject included beans"]
J --> K["Run JavascriptFunction"]
K --> L["Default: return String"]
K --> M["ObjectResult: return Object / Map / List"]
Execution flow
When
JavascriptService.execute(...) is called, the service:- Opens a Rhino
Context. - Creates a standard JavaScript scope with
initStandardObjects(). - Injects default variables and functions into the scope:
-
console -
logger -
beanContext -
getBean(name) -
properties
-
- Injects every entry from
parametersdirectly into the scope. - Injects beans registered through
includeBeanName(...). - Delegates execution to a
JavascriptFunction. - Returns the result to Java.
Default objects available in scripts
Inside JavaScript, you can directly use:
console.log("Hello", name); logger.info("Running script"); properties.get("siteName"); var service = getBean("someService");
Where:
-
parametersare injected directly as named variables. -
propertiescomes from the application properties. -
getBean(name)retrieves a bean by name from the bean context. -
beanContextis also exposed to the scope. -
console.log(...)prints a simple log to standard output. -
loggeris the service logger.
Example:
Map<String, Object> parameters = new HashMap<>(); parameters.put("name", "EzyPlatform"); Object result = javascriptService.execute( "var greeter = getBean('greetingBean'); greeter.greet(name)", parameters );
The script can use
name directly:var greeter = getBean('greetingBean'); greeter.greet(name)
Default string result
The simplest API is:
Object result = javascriptService.execute(
"name + ' platform'",
parameters
);
This uses
DefaultJavascriptFunction.If the script returns a valid value, the result is converted to a
String using toString().For example:
21 * 2
returns:
"42"
If the script is blank, returns
null, or returns undefined, the service returns an empty string.Returning objects with ObjectResultJavascriptFunction
When structured data is needed, use
ObjectResultJavascriptFunction:
Object result = javascriptService.execute(
parameters,
new JavascriptService.ObjectResultJavascriptFunction(
"({ id: 1, name: name, tags: ['admin', 'web'], active: true })"
)
);
The Java result will be a
Map:
{
id: 1,
name: "EzyPlatform",
tags: ["admin", "web"],
active: true
}
ObjectResultJavascriptFunction handles common types as follows:- JavaScript object ->
Map<String, Object> - JavaScript array ->
List<Object> -
string->String -
number->Number -
boolean->Boolean -
nullorundefined->null
Nested objects and arrays are also supported.
Example:
({
user: {
id: 1,
name: "admin"
},
roles: ["admin", "editor"],
enabled: true
})
This is converted into a
Map containing nested Map, List, String, Number, and Boolean values.Including beans with aliases
In addition to dynamically retrieving beans with
getBean(name), the service still supports including beans into the scope with fixed aliases:
javascriptService.includeBeanName(
"sumBean",
"calculator"
);
The script can then use:
calculator.sum(a, b)
This is useful when a plugin or runtime always needs to expose a known set of beans to scripts.
If a bean does not exist in the bean context, that alias will not be injected into the scope.
The javascript_service_bean_names setting is no longer used
In the current version,
JavascriptService no longer reads bean mappings from the javascript_service_bean_names setting.That means the following parts from the previous article are no longer accurate:
- reading bean mappings from settings,
- setting cache,
- refreshing based on last updated time,
- setting-based aliases overriding aliases included in code.
Currently, there are two main ways to access beans in scripts:
var service = getBean("javaBeanName");
or include the bean in Java first:
javascriptService.includeBeanName("javaBeanName", "jsAlias");
then use:
jsAlias.doSomething()
Usage in admin and web
In practice, developers usually use the runtime-specific wrappers:
-
AdminJavascriptServicein the admin runtime -
WebJavascriptServicein the web runtime
Both services inherit the same mechanism from
JavascriptService. They share the same scope creation, parameter injection, bean exposure, and Rhino execution behavior.
Example: returning API data
A useful new use case is writing a script that calls a Java service, builds a JavaScript object, and returns it to Java as structured data.
Example:
Map<String, Object> parameters = new HashMap<>(); parameters.put("requestArguments", arguments); return javascriptService.execute( parameters, new JavascriptService.ObjectResultJavascriptFunction( "var userService = getBean('userService');" + "var user = userService.getUserById(requestArguments.getParameter('id'));" + "({" + " id: user.getId()," + " name: user.getName()," + " active: user.isActive()" + "})" ) );
The script returns a JavaScript object:
({
id: user.getId(),
name: user.getName(),
active: user.isActive()
})
Java receives a
Map, which is convenient for returning a JSON response or further processing.Accessing Java classes from JavaScript
Because the service uses Mozilla Rhino, scripts can access Java classes through
Packages.Example:
var JavaLong = Packages.java.lang.Long; var value = JavaLong.valueOf("123");
You can also use Java classes to call APIs, builders, models, filters, or internal services if the runtime allows it.
Security note
Scripts run with powerful access to the application runtime:
- reading
properties, - calling
getBean(...), - accessing
beanContext, - invoking Java beans,
- accessing Java classes through Rhino.
For that reason, scripts passed to
JavascriptService must come from trusted sources, such as internal configuration or application code. Do not pass user-controlled JavaScript directly into this service.
When to use each option
Use
execute(script, parameters) when:- you only need a string result,
- the script is simple,
- the result is used for text rendering or small calculations.
Use
ObjectResultJavascriptFunction when:
- you need to return an object,
- you need to return a list,
- you want to preserve
number,boolean, andstringvalues, - you want to build a JSON-style response from JavaScript.
Use
getBean(name) when:
- you need to retrieve beans dynamically inside the script,
- you do not want to include aliases beforehand.
Use
includeBeanName(...) when:
- scripts frequently use the same bean,
- you want a shorter and more readable alias,
- you want explicit configuration in plugin or runtime code.
Conclusion
JavascriptService is now a flexible runtime bridge between JavaScript and Java beans. The new version is simpler in bean configuration because it no longer depends on setting-based mappings or cache refreshes, while becoming more powerful in execution through JavascriptFunction and ObjectResultJavascriptFunction.