Truffle 语言和工具迁移到 Java 模块

自 23.1 版本起,Truffle 主要将语言和工具作为从 Java VM 模块路径加载的 Java 模块使用。出于兼容性原因,仍支持从语言或工具主目录加载语言和工具。然而,此方法已被弃用,并将在未来版本中移除。此更改的原因如下:

  1. Truffle 应在所有 JDK 上以相同方式使用。
  2. Truffle 不属于 Java VM jimage 的一部分,它作为常规的 JVM VM 模块路径库使用。
  3. 对于嵌入方而言,从模块路径加载语言和工具要容易得多,并且可以与 Apache Maven 等工具开箱即用。
  4. Java 模块系统保证了强大的封装性和可靠的配置。

模块迁移 #

有关迁移到 Java 模块的一般信息,请参阅 development-with-jdk-9。Truffle 模块分两个版本发布:开放式 Truffle 和封闭式 Truffle。开放式 Truffle 在其模块描述符中导出所有 API 包。另一方面,封闭式 Truffle 不在模块描述符中导出 API 包。相反,它在运行时动态地将 API 包导出到提供语言或工具的模块,以及语言或工具模块读取的模块。开放式 Truffle 旨在用于测试和编译时目的,而封闭式 Truffle 必须用于生产环境。要正确地将语言或工具作为模块加载,需要执行以下迁移步骤:

  1. 定义一个需要 org.graalvm.truffle 模块的具名 Java 模块。
  2. 对于此模块提供的每个 Truffle 语言,使用以下指令注册语言提供程序:
    provides TruffleLanguageProvider with <LanguageClass>Provider 指令。
  3. 对于此模块提供的每个 Truffle 工具,使用以下指令注册工具提供程序:
    provides TruffleInstrumentProvider with <InstrumentClass>Provider 指令。
  4. 如果使用 @GenerateLibrary(defaultExportLookupEnabled = true) 启用了默认导出查找来导出库,则必须使用 com.oracle.truffle.api.library.provider.DefaultExportProvider 服务的 provides 指令,在模块描述符中注册 DefaultExportProvider 的生成实现。如果您使用 mx 构建语言或工具,则 provides 指令会自动生成。
  5. 如果使用 @ExportLibrary(useForAOT = true) 导出 AOT 库,则必须使用 com.oracle.truffle.api.library.provider.EagerExportProvider 服务的 provides 指令,在模块描述符中注册 EagerExportProvider 的生成实现。如果您使用 mx 构建语言或工具,则 provides 指令会自动生成。
  6. 如果您的语言或工具已经有一个模块描述符,请确保它在模块描述符中不提供任何已弃用的 com.oracle.truffle.api.library.EagerExportProvidercom.oracle.truffle.api.library.DefaultExportProvider 接口的实现。它们必须被 com.oracle.truffle.api.library.provider.EagerExportProvidercom.oracle.truffle.api.library.provider.DefaultExportProvider 替换。在模块描述符中提供这些已弃用的接口将在封闭式 Truffle 上创建模块层时导致错误。
  7. 语言或工具不得在模块描述符中提供 JDK 服务或第三方库的服务。这是为了避免语言在没有必要的动态导出情况下被 JDK 或第三方加载。
  8. Java 应用程序可能常用的语言依赖项(如 ICU4J)应进行遮蔽处理,以避免与嵌入式模块产生冲突。
  9. 如果语言或工具不暴露任何 API,建议尽可能保持模块的封装性,并避免导出任何包。否则,请导出 API 包。如果内部 API 仅由已知模块使用,建议使用 export <package> to <module> 语法的限定导出。

以下是简单语言的模块描述符示例。

module org.graalvm.sl {
  requires java.base;
  requires java.logging;
  requires jdk.unsupported;
  requires org.antlr.antlr4.runtime;
  requires org.graalvm.truffle;
  provides  com.oracle.truffle.api.provider.TruffleLanguageProvider with
    com.oracle.truffle.sl.SLLanguageProvider;
}

联系我们