Truffle Unchained — Portable Language Runtimes as Java Libraries

原文はこちら。
The original article was written by Christian Humer (Consulting Researcher, Oracle).
https://medium.com/graalvm/truffle-unchained-13887b77b62c

過去数年間、Truffle言語はguと呼ばれる組み込みのGraalVMアップデータツールを使用してインストールしていました。言語をインストールするには、Oracle GraalVMをダウンロードし、gu installコマンドを実行してコンポーネントをダウンロードして展開します。GraalVM for JDK 21とTruffle/Polyglot 23.1のリリースとともに、私たちはguを削除し、代わりにMaven依存関係として言語を提供するようになりました。このエントリでは、なぜこの変更が必要だったのか、それによって何が得られるのか、そして恩恵を受けるために何をする必要があるのかについて掘り下げてみたいと思います。

What was wrong?

JDKに直接言語をインストールする古いモデルにはメリットがありました。例えば、言語の依存関係のためにクラスやモジュールのパスを生成する必要がありませんでした。インストール後、JavaアプリケーションやJavaコンパイラは、自動的に言語の依存関係を拾い上げます。さらに、JDKから任意の言語を簡単に起動できる言語ランチャーも出しました。何年もかけて、私たちはコミュニティからのフィードバックから、このアプローチにはいくつかの根本的な問題があることがわかりました。

  • インストールされたアプリケーションとランタイムは、不変のままであるはずだ。GraalVM Updaterは、インストールを修正するため、不変性を必要とするシステムやパッケージ・マネージャーとの連携が難しくなった。
  • 言語のアップグレードには、JDKのアップグレードと変更が必要だった。このため、あらゆる言語のアップグレード・プロジェクトが、JDKのアップグレード・プロジェクトになった。実際のところ、別々のチームがこれらのアップグレードを行う場合、これはさらに難しくなる可能性がある。
  • Javaランタイムに組み込まれた追加言語ランチャーは、Javaコミュニティにとっては異質であり、同時に他の言語エコシステムにとっても異質である。言い換えれば、多くの人はPythonランチャーがJDKのbinディレクトリにあることを快く思っていない。
  • 既存のツールの不足により、GraalVM Updaterのような追加のパッケージマネージャを使用することは、さらなる統合の複雑さを引き起こしていた。例えば、JavaアプリケーションがJavaScriptのような言語ランタイムへの依存を表現する方法がない。

What did we change?

何ヶ月かの集中作業の結果、ついにTruffleをJDKから解放する準備が整いました。GraalVM for JDK 21から、以下の変更を行います。

  • (GraalVM開発チームで)開発されるすべてのPolyglot言語ランタイムは、Maven CentralからJavaライブラリとして利用できるようになりました。
  • 今後のPolyglotバージョンは、最新のOracle GraalVM長期サポート・リリースと下位互換性があります。私たちは、これをJDK 21用のGraalVMから始めています。
  • GraalVMアップデータは、ディストリビューションから削除しました。代替手段はありません。
  • 私たちは、NodeやLLVMのような、これまでそのようなディストリビューションがなかった言語のために、より多くのスタンドアロンディストリビューションをリリースします。また、JVM-standaloneと呼ばれるGraalVM JDKがプリインストールされた専用ビルドを各言語に提供します。
  • 最適化ランタイムを使用する場合は、JDK 21用のGraalVMを使用する必要があります。

[GR-46219] Remove the GraalVM Updater #6855
https://github.com/oracle/graal/issues/6855
Embedding Languages
https://graalvm.org/latest/reference-manual/embed-languages/#runtime-optimization-support

How to migrate?

移行をできるだけ簡単にするために、全ての成果物を org.graalvm.polyglot グループにグループ化し、簡単にアクセスできるようにしました。

Maven Central: org.graalvm.polyglot
https://central.sonatype.com/namespace/org.graalvm.polyglot

こうすることで、言語コンポーネント識別子だけ知っていればよくなります。guで使用されるすべてのコンポーネント識別子は、MavenアーティファクトIDとして使用できるようになりました。例えば、JavaScriptを埋め込むためのMaven設定は次のようになります。

<dependency> 
    <groupId>org.graalvm.polyglot</groupId> 
    <artifactId>polyglot</artifactId> 
    <version>23.1.0</version> 
</dependency>
<dependency> 
    <groupId>org.graalvm.polyglot</groupId> 
    <!-- Select language: js, ruby, python, java, llvm, wasm, languages -->
    <artifactId>js</artifactId> 
    <version>23.1.0</version> 
    <type>pom</type>
</dependency>

Gradleだと設定がさらに短くなります。

dependencies {
    implementation("org.graalvm.polyglot:polyglot:23.1.0")
    // Select language: js, ruby, python, java, llvm, wasm, languages
    implementation("org.graalvm.polyglot:js:23.1.0")
}

すべての依存関係は、デフォルトでGraalVM Free Terms and Conditions (GFTC)を使用してライセンス許諾されています。

GraalVM Free Terms and Conditions (GFTC)
https://oracle.com/downloads/licenses/graal-free-license.html

オープンソースライセンスのみを使用するコミュニティバージョンを使用するには、-communityという接尾辞を追加します。例えば、js-community は GFTC ライセンスの拡張機能を持たない JavaScript を指します。

【注】すべてのPolyglot APIは、以前のバージョンと完全な互換性を保っています。このリリースでJavaコードを変更する必要はありません。

また、GraalVM SDKモジュールをより細かいモジュールに分割しました。polyglot embeddingのためには、今後org.graalvm.polyglot:polyglot依存性を使ってください。Javaモジュールシステムを使用する場合、必要なJavaモジュールとしてorg.graalvm.sdkorg.graalvm.polyglotに置き換え可能です。非推奨の GraalVM SDK モジュールを引き続き Maven Central に展開していますので、すぐに移行する必要はありません。

新しい依存関係を使用するための詳細情報は、以下のドキュメントをご覧ください。

Dependency Setup – Embedding Languages
https://graalvm.org/latest/reference-manual/embed-languages/#dependency-setup

簡単に始められるよう、サンプルのMavenとGradleの設定を持つ新たなpolyglot embeddingデモのリポジトリも作成しました。

Demonstration repository showing polyglot embedding with GraalVM for JDK 21 using Maven and Gradle.
https://github.com/graalvm/polyglot-embedding-demo/

GraalVM Updaterが削除されたので、このリリースでguを利用する必要がなくなります。いずれかの言語ランチャーを使用していた場合は、代わりにGraalVM for JDK 21リリースの一部として提供されるスタンドアロンのダウンロードを使用してください。

Download GraalVM
https://graalvm.org/downloads/

What’s better?

以下の理由でこれらの変更に価値があると考えています。

Ecosystem Compatibility
【エコシステムの互換性】
どのエコシステム出身のユーザーであっても、違和感を感じないはずです。Java開発者は、毎日Javaライブラリを使用するように、Mavenの依存関係として言語を使用できるようになりました。言語ランチャーのユーザーは、参照実装のように見た目も使い勝手も改善されたスタンドアロン・ディストリビューションを手に入れることができます。
Platform Independent JARs
【プラットオーム非依存のJAR】
Java開発者は、デフォルトでプラットフォーム非依存のライブラリを期待しています。私たちがデプロイするすべてのJARファイルには、私たちがサポートするすべてのプラットフォームのリソースとネイティブ・ライブラリが含まれています。これにより、依存関係を持つアプリケーションをプラットフォーム間でシームレスに移動できます。
Improved Immutability
【不変性の向上】
Oracle GraalVMとGraalVM CEは現在、不変です。言語の更新にあたり、Mavenの依存関係を使用してJDKのインストールを変更する必要はありません。このしくみは、不変性を必要とするプラットフォームやパッケージマネージャにとって助けになります。
Simplified Language Upgrades
【簡単な言語アップデート】
Java開発者としての言語ランタイムのアップグレードは、Maven依存関係のバージョン番号を変更するのと同じくらい簡単になります。言語のアップグレードは、JDKのアップグレードとは別に実行できるようになりました。
Backward Compatibility
【後方互換性】
以前のLTSリリースのJDKに対する後方互換性により、言語の埋め込み (language embeddings) は、新たなpolyglot言語機能の恩恵を受けつつ、継続して古いJDKを利用できます。
Standardized Configuration
【構成の標準化】
polyglot runtimeをモジュールまたはクラスパスを使用して追加するようになりました。これは、Native Imageドライバを含むすべてのJDKで同じように機能します。これにより、複数のJDKで動作するシステムとの統合が簡単になります。

What’s worse?

言語使用方法の変更は破壊的な変更ですし、セットアップスクリプトの一部としてGraalVM Updaterを使用している場合、移行が必要になる可能性があるため、ごまかすことはできません。さらに、このリリースには2つの既知の問題があり、今後のリリースで修正する予定です。

Polyglot programming前章で述べたように、JDKのスタンドアロン言語ランチャーを使用していた場合、(maven依存関係ではなく)スタンドアロン版の言語ダウンロードを使用する必要があります。スタンドアロン版のディストリビューションでは、追加言語の追加やインストールのサポートに制限があります。PythonとRubyはすでにJVMスタンドアロンディストリビューションにこの機能のサポートを追加しています。他の言語もその後のリリースで追随する予定です。また、Polyglot Embedding APIを使って複数の言語を使い続けることもできます。

Polyglot Programming
https://graalvm.org/latest/reference-manual/polyglot-programming/
Polyglot API – Python
https://github.com/oracle/graalpython/blob/master/docs/user/Interoperability.md#the-polyglot-api
Polyglot API – Ruby
https://github.com/oracle/truffleruby/blob/master/doc/user/polyglot.md#installing-other-languages
Limited Polyglot Isolate Support
【限定されたPolyglot分離サポート】
GraalVM for JDK 21リリースでは、Polyglot分離イメージとしてMaven CentralにJavaScriptのみを展開します。今後のリリースでより多くの言語を展開する予定です。早くPolyglot分離イメージとして言語を使いたい場合はお知らせください。

Polyglot Isolates
https://www.graalvm.org/latest/reference-manual/embed-languages/#polyglot-isolates

Why now? Why not earlier?

このステップは、ある人にとっては当たり前のように思えるかもしれませんが、私たちが2019年に初めてGraalVMをリリースした当初はそうではありませんでした。なぜこれをもっと早く/最初からやらなかったのかを概説することは理にかなっています。この章では多くの詳細な説明に入りますが、いくつかの背景について詳しく説明した上で、この決定を説明する必要があると考えています。

Strong coupling with the compilerTruffle最適化ランタイムとGraalコンパイラは、歴史的に長い間一緒に開発されてきました。実際、GraalコンパイラモジュールにはTruffle最適化ランタイムが含まれていました。2つのコンポーネントが長い間同じモジュール内に存在すると、時間の経過とともに結合が強くなっていきます。今回の変更 (=Truffle Unchained) に必要な作業の大部分は、コンパイラとTruffleランタイムの結合を解除することでした。
Variability2つのコンポーネントを分離し、独立して使用できるようにすると、さらに可変性が加わります。以前は、Truffle最適化ランタイムとGraalコンパイラは同じバージョンであることが保証されていました。この追加的な可変性を可能にするために、これら2つのコンポーネント間に新しいAPIを導入する必要がありました。このようなインターフェースは、プラットフォームの進化をより複雑なものにしますが、ユーザーがバージョン問題を心配する必要がなくなるのが望ましいわけです。
Encapsulationembedding APIの成果物が実装の詳細を十分に隠蔽することを保証したいと考えています。これは、embedderのためのAPIの安定性と、同時に言語実装の独立した進化のバランスをとる必要があるためです。GraalVMが2019年に最初にリリースされたとき、私たちはJava 8をサポートして出荷しましたが、モジュールによるカプセル化 (module encapsulation) は不可能でした。それゆえ、カプセル化のためにクラス・ローダーの分離に頼らざるを得ませんでしたが、クラス・ローダーの分離は、既知の場所から言語をロードできる場合にのみ機能しました。それ以来、私たちはJava 8のサポートをやめたので、Javaモジュール・カプセル化に頼ることができるようになりました。このおかげで、言語依存関係がクラスやモジュールのパスで提供されている場合にもJavaモジュール・カプセル化が使えます。
Resource files多くの言語では、実行するためにプラットフォーム固有のファイルやネイティブ・ライブラリが必要です。これらのファイルの多くは、互換性のために物理的にディスクに保存する必要があります。以前は、GraalVM Updaterが言語をインストールする際に、これらのリソースをインストールしていました。今回の変更で、新しいInternal Resources APIを開発しました。

InternalResource (GraalVM Truffle Java API Reference)
https://graalvm.org/truffle/javadoc/com/oracle/truffle/api/InternalResource.html

これは、ディスク上のローカルファイルを必要とする言語実装が使用できるAPIで、言語が新たなプラットフォームで初めて使用されるときに、JARファイルからバージョン管理されたローカル・キャッシュ・フォルダーへのファイルとネイティブ・ライブラリの展開を可能にします。このような機能は複雑なため、これまでは実現できませんでしたが、最終的にはこの弾丸を食らわなければなりませんでした。
Enterprise extension supportGraal コンパイラと Truffle ランタイムを分離したのと同様に、Oracle GraalVM の一部としてのみ動作するエンタープライズ拡張機能も分離する必要がありました。私たちは、Oracle GraalVMで使用される場合にのみアクティブになるようにエンタープライズ拡張機能を更新しました。
さらに、最近のGFTCライセンスへの変更により、エンタープライズ拡張機能をMaven Centralにデプロイできるようになりました。

Tell us what you think!

コミュニティ・チャンネルでご意見をお聞かせください。

Community
https://graalvm.org/community/

新しいモデルがお好みですか、それとも古いモデルですか?移行にあたってどのようにご支援できそうでしょうか?GitHub で遭遇するかもしれない問題を遠慮なく報告してください。

GraalVM Issues
https://github.com/oracle/graal/issues/new/choose

Further Reading

The GraalVM for JDK 21 Release Notes
https://docs.oracle.com/en/graalvm/jdk/21/docs/release-notes/
Embedding Languages
https://graalvm.org/latest/reference-manual/embed-languages/

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください