From 1cefa3e36de2dc7ccbc5591e8dc50cdabac10d0f Mon Sep 17 00:00:00 2001 From: Eric Wittmann Date: Mon, 14 Jul 2025 11:56:02 -0400 Subject: [PATCH 1/2] Added a blog post to announce the quarkus-quickjs4j extension --- _posts/2025-07-14-quickjs4j.adoc | 326 +++++++++++++++++++++++++++++++ 1 file changed, 326 insertions(+) create mode 100644 _posts/2025-07-14-quickjs4j.adoc diff --git a/_posts/2025-07-14-quickjs4j.adoc b/_posts/2025-07-14-quickjs4j.adoc new file mode 100644 index 00000000000..8845df6c2cf --- /dev/null +++ b/_posts/2025-07-14-quickjs4j.adoc @@ -0,0 +1,326 @@ +--- +layout: post +title: 'Introducing Quarkus quickjs4j: Seamless JavaScript Integration in Your Quarkus Applications' +date: 2025-07-14 +tags: javascript, integration, cdi, build-time +synopsis: A new Quarkiverse extension that brings JavaScript execution to your Java applications with compile-time code generation and full CDI integration. +author: ewittman +--- +:imagesdir: /assets/images/posts/quickjs4j +ifdef::env-github,env-browser,env-vscode[:imagesdir: ../assets/images/posts/quickjs4j] + +== Introduction + +We're excited to announce the release of the Quarkus quickjs4j extension, a powerful new addition to the +Quarkus ecosystem that enables seamless execution of JavaScript code within your Java applications. Built +on top of the https://github.com/roastedroot/quickjs4j[quickjs4j library], this extension brings the +lightweight QuickJS JavaScript engine to Quarkus with full CDI integration and compile-time optimizations. + +Whether you need to execute dynamic business logic, implement configurable rules engines, or integrate with +JavaScript-based algorithms, the Quarkus quickjs4j extension provides a type-safe, performant solution that +leverages Quarkus's build-time processing capabilities. + +== Why JavaScript in Java Applications? + +Quarkus applications often need to execute dynamic logic that can be modified without recompiling the entire +application. JavaScript provides an excellent solution for this use case, offering: + +- **Dynamic Configuration**: Update business rules and logic without application restarts +- **Scripting Capabilities**: Enable power users to customize application behavior +- **Algorithm Integration**: Leverage existing JavaScript libraries and algorithms +- **Rapid Prototyping**: Quickly test and iterate on complex logic + +The Quarkus quickjs4j extension makes this integration seamless while maintaining the performance and developer +experience you expect from Quarkus. + +== Key Features + +=== Compile-time Code Generation +The extension automatically generates CDI beans and proxy classes for your JavaScript interfaces during build +time, ensuring optimal performance and early error detection. + +=== Full CDI Integration +JavaScript interfaces are first-class citizens in your Quarkus application, injectable like any other CDI bean. + +=== Flexible Script Loading +Load JavaScript files from multiple sources: +- Classpath resources (recommended for packaged scripts) +- Filesystem paths (for dynamic script loading) +- URLs (for remote script execution) +- Anywhere else (using the optional Factory pattern) + +=== Context Support +Pass Java objects as context to JavaScript execution, enabling bidirectional communication between Java and +JavaScript code. + +=== Sandboxed Execution +QuickJs4J provides a secure and efficient way to execute JavaScript within Java. By running code in a sandbox, +it ensures: + +- Memory safety – JavaScript runs in isolation, protecting your application from crashes or memory leaks. +- No system access by default – JavaScript cannot access the filesystem, network, or other sensitive resources unless explicitly allowed. +- Portability – Being pure Java bytecode, it runs wherever the JVM does. +- Native-image friendly – Compatible with GraalVM's native-image for fast, lightweight deployments. + +Whether you're embedding scripting capabilities or isolating untrusted code, QuickJs4J is designed for safe and +seamless integration. + +== Getting Started + +Adding the extension to your Quarkus application is straightforward. First, add the dependency to your `pom.xml`: + +[source,xml] +---- + + io.quarkiverse.quickjs4j + quarkus-quickjs4j + ${quarkus-quickjs4j.version} + +---- + +You'll also need to enable the annotation processor for code generation: + +[source,xml] +---- + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + io.quarkiverse.quickjs4j + quarkus-quickjs4j + ${quarkus-quickjs4j.version} + + + + + + +---- + +== Simple Example: JavaScript Calculator + +Let's create a simple calculator to demonstrate the extension's capabilities. + +First, define a Java interface annotated with `@ScriptInterface` and `@ScriptImplementation`: + +[source,java] +---- +package com.example; + +import io.roastedroot.quickjs4j.annotations.ScriptInterface; +import io.quarkiverse.quickjs4j.annotations.ScriptImplementation; + +@ScriptInterface +@ScriptImplementation(location = "calculator.js") +public interface Calculator { + int add(int a, int b); + int multiply(int a, int b); +} +---- + +Next, create the JavaScript implementation in `src/main/resources/calculator.js`: + +[source,javascript] +---- +function add(a, b) { + return a + b; +} + +function multiply(a, b) { + return a * b; +} + +export { add, multiply }; +---- + +Finally, inject and use the calculator in your Quarkus application: + +[source,java] +---- +package com.example; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; + +@ApplicationScoped +public class MathService { + + @Inject + Calculator calculator; + + public int performCalculation() { + int sum = calculator.add(5, 3); // Returns 8 + int product = calculator.multiply(4, 7); // Returns 28 + double quotient = calculator.divide(10.0, 2.0); // Returns 5.0 + + return sum + product + (int) quotient; + } +} +---- + +That's it! The extension handles all the complexity of JavaScript execution, type conversion, and CDI +integration behind the scenes. + +== Advanced Features + +=== Context Objects for Bidirectional Communication + +A powerful feature of quickjs4j is the ability to provide Java context objects that JavaScript code +can invoke: + +[source,java] +---- +@ScriptInterface(context = CalculatorContext.class) +@ScriptImplementation(location = "calculator.js") +public interface Calculator { + int add(int a, int b); + int multiply(int a, int b); +} + +@ApplicationScoped +public class CalculatorContext { + public void log(String message) { + System.out.println("Calc>> " + message); + } +} +---- + +Your JavaScript code can then call these Java methods: + +[source,javascript] +---- +function add(a, b) { + Calculator_Builtins.log(`Adding ${a} + ${b}`); + return a + b; +} + +function multiply(a, b) { + Calculator_Builtins.log(`Multiplying ${a} * ${b}`); + return a * b; +} + +export { add, multiply }; +---- + +=== Factory Pattern for Dynamic Scripts + +For scenarios where you need to load scripts dynamically at runtime, use the factory pattern: + +[source,java] +---- +@ApplicationScoped +public class DynamicMathService { + + @Inject + CalculatorContext context; + + @Inject + ScriptInterfaceFactory calculatorFactory; + + public void executeCustomScript() { + // Load your javascript from some dynamic source + String scriptContent = loadDynamicScriptContent(); + + // Create calculator instance with dynamic script + Calculator calculator = calculatorFactory.create(scriptContent, context); + + // Use the calculator + int result = calculator.add(10, 20); + System.out.println("Result: " + result); + } +} +---- + +This approach is perfect for applications that need to execute user-provided scripts or +load scripts from external sources. Note that the execution of the script is fully sandboxed. +Only the methods exposed by the Context can be invoked from within the script. + +== Error Handling and Debugging + +JavaScript errors are propagated as Java exceptions, making debugging straightforward: + +[source,java] +---- +try { + double result = calculator.divide(10, 0); +} catch (RuntimeException e) { + logger.error("JavaScript execution failed: {}", e.getMessage(), e); + // Handle the error appropriately +} +---- + +== Build-time Magic + +Behind the scenes, the extension performs build-time code generation, creating: + +1. **CDI Bean Classes**: `{InterfaceName}_CDI` - Injectable CDI beans +2. **Factory Classes**: `{InterfaceName}_Factory` - Injectable factory beans +3. **Proxy Classes**: `{InterfaceName}_Proxy` - Generated by quickjs4j +4. **Context Builtins**: `{ContextName}_Builtins` - JavaScript-accessible Java methods + +This build-time approach ensures minimal runtime overhead while providing full IDE +support with code completion and type checking. + +== Performance Considerations + +The QuickJS engine is designed for lightweight, fast JavaScript execution. Combined with +Quarkus's build-time optimizations, the extension provides: + +- **Fast Startup**: Minimal impact on application startup time +- **Low Memory Footprint**: Efficient memory usage for JavaScript execution +- **Native Image Support**: Full compatibility with GraalVM native images +- **Build-time Validation**: Early detection of interface mismatches and errors + +== Use Cases + +The Quarkus quickjs4j extension is perfect for: + +- **Business Rules Engines**: Implement configurable business logic +- **Template Processing**: Generate dynamic content with JavaScript templates +- **Algorithm Integration**: Leverage existing JavaScript algorithms and libraries +- **User Scripting**: Allow power users to customize application behavior +- **Configuration Logic**: Implement complex configuration scenarios + +== Current Status and Future Plans + +The extension is currently in **experimental status**, meaning APIs may evolve based on +community feedback. We're actively working on: + +- Enhanced error reporting and debugging capabilities +- Performance optimizations +- Additional JavaScript engine options +- Improved IDE integration and tooling + +== Getting Involved + +The Quarkus quickjs4j extension is part of the Quarkiverse ecosystem and welcomes community +contributions. Whether you're interested in: + +- Reporting bugs or requesting features +- Contributing code improvements +- Sharing use cases and examples +- Improving documentation + +Visit our https://github.com/quarkiverse/quarkus-quickjs4j[GitHub repository] to get involved! + +== Conclusion + +The Quarkus quickjs4j extension opens up exciting possibilities for Java developers who need +to integrate JavaScript execution into their applications. With its compile-time code generation, +full CDI integration, and flexible script loading options, it provides a powerful yet easy-to-use +solution for dynamic code execution. + +Try it out and let us know what you think! We're excited to see what the community builds with this +capability. + +== Links and Resources + +- https://github.com/quarkiverse/quarkus-quickjs4j[Quarkus quickjs4j GitHub Repository] +- https://github.com/roastedroot/quickjs4j[quickjs4j Library] +- https://bellard.org/quickjs/[QuickJS JavaScript Engine] +- https://quarkus.io/extensions/[Quarkus Extensions] +- https://github.com/quarkiverse[Quarkiverse Hub] From fbe13dac779711da52dbd508c06db31cfbc30b5a Mon Sep 17 00:00:00 2001 From: Eric Wittmann Date: Tue, 15 Jul 2025 06:52:34 -0400 Subject: [PATCH 2/2] Updates to the quickjs4j blog post based on PR feedback --- ...ickjs4j.adoc => 2025-07-15-quickjs4j.adoc} | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) rename _posts/{2025-07-14-quickjs4j.adoc => 2025-07-15-quickjs4j.adoc} (92%) diff --git a/_posts/2025-07-14-quickjs4j.adoc b/_posts/2025-07-15-quickjs4j.adoc similarity index 92% rename from _posts/2025-07-14-quickjs4j.adoc rename to _posts/2025-07-15-quickjs4j.adoc index 8845df6c2cf..53941e6f59a 100644 --- a/_posts/2025-07-14-quickjs4j.adoc +++ b/_posts/2025-07-15-quickjs4j.adoc @@ -1,7 +1,7 @@ --- layout: post title: 'Introducing Quarkus quickjs4j: Seamless JavaScript Integration in Your Quarkus Applications' -date: 2025-07-14 +date: 2025-07-15 tags: javascript, integration, cdi, build-time synopsis: A new Quarkiverse extension that brings JavaScript execution to your Java applications with compile-time code generation and full CDI integration. author: ewittman @@ -14,7 +14,8 @@ ifdef::env-github,env-browser,env-vscode[:imagesdir: ../assets/images/posts/quic We're excited to announce the release of the Quarkus quickjs4j extension, a powerful new addition to the Quarkus ecosystem that enables seamless execution of JavaScript code within your Java applications. Built on top of the https://github.com/roastedroot/quickjs4j[quickjs4j library], this extension brings the -lightweight QuickJS JavaScript engine to Quarkus with full CDI integration and compile-time optimizations. +lightweight QuickJS JavaScript engine to both JVM and Native Quarkus, with full CDI integration and +compile-time optimizations. Whether you need to execute dynamic business logic, implement configurable rules engines, or integrate with JavaScript-based algorithms, the Quarkus quickjs4j extension provides a type-safe, performant solution that @@ -180,7 +181,10 @@ public interface Calculator { int add(int a, int b); int multiply(int a, int b); } +---- +[source,java] +---- @ApplicationScoped public class CalculatorContext { public void log(String message) { @@ -292,9 +296,15 @@ community feedback. We're actively working on: - Enhanced error reporting and debugging capabilities - Performance optimizations -- Additional JavaScript engine options +- Configurable JavaScript engine options - Improved IDE integration and tooling +In particular, we have a lot of work to do in optimizing performance. There are +clear tradeoffs to consider around flexibility and speed, as well as customization. +The current experimental implementation takes a very conservative approach to +ensure full sandboxing and thread safety. The result is a slower implementation, +but one that is guaranteed to be thread safe and fully sandboxed. + == Getting Involved The Quarkus quickjs4j extension is part of the Quarkiverse ecosystem and welcomes community @@ -305,7 +315,9 @@ contributions. Whether you're interested in: - Sharing use cases and examples - Improving documentation -Visit our https://github.com/quarkiverse/quarkus-quickjs4j[GitHub repository] to get involved! +Visit our https://github.com/quarkiverse/quarkus-quickjs4j[GitHub repository] to get involved. +We would really love for you to try out quickjs4j in Quarkus and give us feedback. The best +way to evolve the functionality is by hearing from users! == Conclusion @@ -318,9 +330,9 @@ Try it out and let us know what you think! We're excited to see what the communi capability. == Links and Resources +If you want to learn more about QuickJS itself, or the upstream quickjs4j Java project, +here are some helpful links: - https://github.com/quarkiverse/quarkus-quickjs4j[Quarkus quickjs4j GitHub Repository] - https://github.com/roastedroot/quickjs4j[quickjs4j Library] - https://bellard.org/quickjs/[QuickJS JavaScript Engine] -- https://quarkus.io/extensions/[Quarkus Extensions] -- https://github.com/quarkiverse[Quarkiverse Hub]