Federico Mariani created CAMEL-23398:
----------------------------------------
Summary: Add QuickJS JavaScript language using QuickJS4J
Key: CAMEL-23398
URL: https://issues.apache.org/jira/browse/CAMEL-23398
Project: Camel
Issue Type: New Feature
Reporter: Federico Mariani
Add a new `camel-quickjs` language module that uses
[QuickJS4J|https://github.com/roastedroot/quickjs4j] as a lightweight,
pure-Java JavaScript engine alternative to GraalVM Polyglot.
QuickJS4J compiles the QuickJS engine to WebAssembly and translates it to pure
Java bytecode via [Chicory|https://github.com/nicktindall/chicory], requiring
no JNI or native dependencies. This makes it portable across all JVM platforms
(including s390x and ppc64le where GraalVM JS is disabled), GraalVM
native-image compatible, and sandboxed for secure script execution.
Both modules coexist: {{camel-javascript}} (GraalVM, full Java interop) and
{{camel-quickjs}} (pure Java, lightweight).
*Exchange Handling Alternatives*
QuickJS4J communicates between Java and JavaScript via JSON serialization.
Unlike GraalVM's {{HostAccess.ALL}}, live Java objects (Exchange, Message,
CamelContext) cannot be passed directly as bindings. There are three approaches
to handle this:
*Alternative A -- Data-only bindings:*
Expose Exchange data as JSON-serializable values: {{body}}, {{headers}},
{{properties}}, {{exchangeId}}. Scripts can read data but cannot call methods
on Exchange or Message objects. This covers the most common use cases
(filtering, transforming, routing decisions based on headers/body) and is
simple to implement.
{code}
// Works: data access
.when().quickjs("headers.MyHeader == 'foo'")
.transform().quickjs("body.toUpperCase()")
// Does NOT work: method calls on Java objects
.quickjs("exchange.getMessage().setHeader('foo', 'bar')")
{code}
*Alternative B -- HostRef + Builtins bridge:*
Use QuickJS4J's {{HostRef}} mechanism and {{Builtins}} API to register
Java-side host functions (e.g., {{camel.getHeader("foo")}},
{{camel.getBody()}}, {{camel.setBody(...)}}). The Exchange is kept on the Java
side as an opaque reference, and JS calls named bridge functions. This
preserves the ability to read/write Exchange state from scripts but adds
implementation complexity.
{code}
// Would work with bridge functions
.quickjs("camel.setHeader('processed', true); camel.getBody()")
{code}
--
This message was sent by Atlassian Jira
(v8.20.10#820010)