- 适用于 JDK 23 的 GraalVM(最新)
- 适用于 JDK 24 的 GraalVM(抢先体验)
- 适用于 JDK 21 的 GraalVM
- 适用于 JDK 17 的 GraalVM
- 存档
- 开发版本
GraalJS
GraalJS 是一个基于 GraalVM 的快速 JavaScript 语言实现。它符合 ECMAScript 标准,提供与 Java 和其他 Graal 语言的互操作性,以及常用的工具。如果在 GraalVM JDK 上运行,它默认情况下使用 Graal JIT 编译器,提供最佳性能。您也可以将 GraalJS 与 Oracle JDK 或 OpenJDK 结合使用。
对于希望从 Nashorn 或 Rhino 迁移 到支持新的 ECMAScript 标准和功能的 JavaScript 引擎的项目来说,GraalJS 是一个合适的替代品。您可以轻松地将 GraalJS 添加到您的 Java 应用程序中,如下所示。
在 JVM 上使用 GraalJS 入门 #
要将 JavaScript 嵌入到 Java 宿主应用程序中,请通过将其添加为项目依赖项来启用 GraalJS。所有必要的工件可以直接从 Maven Central 下载。所有与嵌入器相关的工件都可以在 Maven 依赖项组 org.graalvm.polyglot 中找到。
以下是 JavaScript 嵌入的 Maven 配置
<dependency>
<groupId>org.graalvm.polyglot</groupId>
<artifactId>polyglot</artifactId>
<version>${graaljs.version}</version>
</dependency>
<dependency>
<groupId>org.graalvm.polyglot</groupId>
<artifactId>js</artifactId>
<version>${graaljs.version}</version>
<type>pom</type>
</dependency>
这将启用 GraalJS,它基于 Oracle GraalVM,并根据 GraalVM 免费条款和条件 (GFTC) 授权。如果您想使用基于 GraalVM Community Edition 构建的 GraalJS,请使用artifactId js-community
而不是 js
。
分步骤创建 Maven 项目,将 JavaScript 嵌入到 Java 中,并运行它。此示例应用程序已通过 GraalVM for JDK 23 和 GraalVM Polyglot API 版本 24.1.0 进行测试。有关如何安装 GraalVM,请参阅 下载页面。
- 在您最喜欢的 IDE 中或从您的终端使用以下结构,创建一个名为“helloworld”的新 Maven Java 项目
├── pom.xml └── src ├── main │ └── java │ └── com │ └── example │ └── App.java
例如,您可以运行以下命令来使用快速入门原型创建一个新的 Maven 项目
mvn archetype:generate -DgroupId=com.example -DartifactId=helloworld -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.5 -DinteractiveMode=false
- 将 App.java 中的内容替换为以下代码
package com.example; import org.graalvm.polyglot.*; import org.graalvm.polyglot.proxy.*; public class App { static String JS_CODE = "(function myFun(param){console.log('Hello ' + param + ' from JS');})"; public static void main(String[] args) { String who = args.length == 0 ? "World" : args[0]; System.out.println("Hello " + who + " from Java"); try (Context context = Context.create()) { Value value = context.eval("js", JS_CODE); value.execute(who); } } }
此示例应用程序使用 Polyglot API 并将 JavaScript 函数作为 Java 值返回。
- 将以下依赖项添加到 pom.xml 中,以包含 JavaScript 引擎 (GraalJS)
<dependencies> <dependency> <groupId>org.graalvm.polyglot</groupId> <artifactId>polyglot</artifactId> <version>${graaljs.version}</version> </dependency> <dependency> <groupId>org.graalvm.polyglot</groupId> <artifactId>js</artifactId> <version>${graaljs.version}</version> <type>pom</type> </dependency> </dependencies>
通过将
graaljs.version
属性添加到<properties>
部分,设置 GraalJS 和 GraalVM Polyglot API 版本。或者,您可以直接用版本字符串替换${graaljs.version}
。在本例中,使用24.1.0
<properties> <graaljs.version>24.1.0</graaljs.version> </properties>
- 将用于将项目编译成 JAR 文件和将所有运行时依赖项复制到目录中的 Maven 插件添加到您的 pom.xml 文件
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.13.0</version> <configuration> <fork>true</fork> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.4.2</version> <configuration> <archive> <manifest> <mainClass>com.example.App</mainClass> </manifest> </archive> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>3.8.0</version> <executions> <execution> <id>copy-dependencies</id> <phase>package</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory>${project.build.directory}/modules</outputDirectory> <includeScope>runtime</includeScope> <includeTypes>jar</includeTypes> </configuration> </execution> </executions> </plugin> </plugins> </build>
- (可选)将 module-info.java 添加到您的应用程序。如果您想在模块路径上运行应用程序,请在 src/main/java 中创建一个 module-info.java 文件,其中包含以下内容
module com.example { requires org.graalvm.polyglot; }
- 编译并打包项目
mvn clean package
- 使用 GraalVM 或另一个兼容的 JDK 运行应用程序。如果您在项目中包含了 module-info.java(步骤 5),您现在可以在模块路径上运行应用程序,使用以下命令之一
java --module-path target/modules:target/helloworld-1.0-SNAPSHOT.jar --module com.example/com.example.App "GraalVM" java -p target/modules:target/helloworld-1.0-SNAPSHOT.jar -m com.example/com.example.App "GraalVM"
否则,您可以使用模块路径上的依赖项和类路径上的应用程序运行
java --module-path target/modules --add-modules=org.graalvm.polyglot -cp target/helloworld-1.0-SNAPSHOT.jar com.example.App "GraalVM" java --module-path target/modules --add-modules=org.graalvm.polyglot -jar target/helloworld-1.0-SNAPSHOT.jar "GraalVM"
或者,您也可以在类路径上运行所有内容(在这种情况下,您需要使用
*
或指定所有 JAR 文件)java -cp "target/modules/*:target/helloworld-1.0-SNAPSHOT.jar" com.example.App "GraalVM" # or using shell expansion: java -cp "$(find target/modules -name '*.jar' | tr '\n' :)target/helloworld-1.0-SNAPSHOT.jar" com.example.App "GraalVM" java -cp "$(printf %s: target/modules/*.jar)target/helloworld-1.0-SNAPSHOT.jar" com.example.App "GraalVM"
注意:我们不建议将所有依赖项捆绑到单个“胖”JAR 中(例如,使用 Maven Assembly 插件),因为它会导致问题,并阻止使用 GraalVM Native Image 进行提前编译。相反,我们建议使用所有
org.graalvm.*
依赖项的原始、独立 JAR 文件,最好是在模块路径上。在 嵌入语言指南 中了解更多信息。
源代码单元可以用字符串表示,如示例所示,也可以用文件、从 URL 读取以及 其他方式 表示。通过包装函数定义 (()
),您将立即返回函数
Value f = context.eval("js", "(function f(x, y) { return x + y; })");
Value result = f.execute(19, 23);
您还可以从 JavaScript 中查找 Java 类型并实例化它们,如下所示
try (Context context = Context.newBuilder()
.allowHostAccess(HostAccess.newBuilder(HostAccess.ALL).build())
.allowHostClassLookup(className -> true)
.build()) {
java.math.BigDecimal v = context.eval("js",
"var BigDecimal = Java.type('java.math.BigDecimal');" +
"BigDecimal.valueOf(10).pow(20)")
.asHostObject();
assert v.toString().equals("100000000000000000000");
}
Polyglot API 提供了许多其他方法来从 Java 访问访客语言代码,例如,通过直接访问 JavaScript 对象、数字、字符串和数组。在 Java 互操作性指南 中了解有关 JavaScript 到 Java 互操作性的更多信息,并找到更多示例。
相关文档 #
GraalJS 也作为独立发行版提供,您可以从 GitHub 下载。了解更多信息,请访问 此处。
我们为 GraalJS 用户提供以下文档
迁移指南
了解有关从旧环境迁移的更多信息