Add GraalJS engine support alongside Nashorn#1180
Draft
synecdoche wants to merge 1 commit into
Draft
Conversation
Add support for the GraalJS JavaScript engine as an alternative to Nashorn, allowing the library to use whichever engine is available at runtime. GraalJS is tried first, falling back to Nashorn. GraalJS is configured with three polyglot options: - polyglot.js.allowAllAccess=true: enables Java.type() interop needed by helpers.nashorn.js to bridge Java classes into JavaScript. - polyglot.js.nashorn-compat=true: enables Nashorn-like bean property access so that `bean.name` in JS resolves to `getName()` on Java objects, which the existing helper bridge relies on. - polyglot.js.ecmascript-version=2022: overrides the ES5 default imposed by nashorn-compat mode, allowing ES6+ syntax (let, const, arrow functions) in user-supplied helper scripts. The adaptES6Literals() method in DefaultHelperRegistry, which converts let/const to var for Nashorn's ES5 parser, is now only applied when actually running on Nashorn. GraalJS handles ES6+ natively with the ecmascript-version override. Both engine dependencies (nashorn-core, js-scriptengine + polyglot js) are marked <optional>true</optional> in handlebars/pom.xml so consumers choose which engine to include. The handlebars-maven-plugin adds an explicit nashorn-core dependency since it needs a concrete engine for template precompilation. To run tests with a specific engine: - GraalJS only: -Dmaven.test.classpathDependencyExcludes=org.openjdk.nashorn:nashorn-core - Nashorn only: -Dmaven.test.classpathDependencyExcludes=org.graalvm.js:js-scriptengine
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is a proof of concept PR for adding GraalJS [1] engine support, written against the 4.5.1 release. Nashorn has been removed from the JDK, and it hasn't received active development, while GraalJS continues to track the ECMAScript standard [2]. Additionally, GraalJS can use the Graal JIT compiler to compile JavaScript to native code, yielding significant benchmark improvements in some cases [3] but may or may not apply to typical Handlebars.java use cases. The pros and cons have GraalJS for Handlebars.java has come up before; see [4].
This implementation selects an engine at runtime, preferring Nashorn by default. There is an additional Java property to select an engine explicitly:
hbs.js_engine. However, it's rare that both engines would be available, so it might be better to use thejavaxAPIs to just instantiate whichever is available, which I understand to be possible but haven't yet tried.I have tested it with Corretto JDK 25 [5] with the following command, and there were no test regressions:
If there is interest in taking this, I can clean it up / refactor as needed. I don't have much experience with Handlebars.java as such, so please excuse naiveté on my part, especially regarding how
Handlebars.javais typically used.Thoughts?
[1] https://www.graalvm.org/javascript/
[2] https://www.graalvm.org/latest/reference-manual/js/JavaScriptCompatibility/
[3] https://github.com/simonis/GraalJsTest/#benchmark-results
[4] #696
[5] https://docs.aws.amazon.com/corretto/latest/corretto-25-ug/downloads-list.html