GraalVMは、Javaで記述されたJava仮想マシン(JVM)を提供する新コンポーネント"Java on Truffle"を含む、メジャーバージョン21.0をリリースした。GraalVMはそれ自体、JavaやPython、JavaScriptなど複数言語で記述されたアプリケーション実行のための共有ランタイムを提供する、多言語仮想マシンである。
これまでのリリースでは、GraalVM上でJavaアプリケーションを実行するには、GraalVMのJust-In-Time(JIT)コンパイラでJava HotSpot VMを使うか、あるいはGraalVM Native Imageを使ってネイティブ実行コードにコンパイルする必要があった。今回のリリースで、Truffleフレームワークを使ってJavaで記述されたJVMであるJava on Truffleにより、Javaアプリケーション実行の新たな選択肢が加わったことになる。
EspressoというコードネームのJava on Truffleは、GraalVM Updaterのgu
を使ってインストールすることができる。gu
は、GraalVMのコアディストリビューションに含まれていないパッケージのダウンロードとインストールを行う、パッケージマネージャである。
gu install espresso
Java on Truffleを使ってJavaアプリケーションを実行するには、javaコマンドに-truffle
オプションを渡す必要がある。
java -truffle -jar awesomeApp.jar
Java on Truffleは、バイトコードインタプリタやJava Native Interface(JNI)、Java Debug Wire Protocol(JDWP)など、JVMのコアコンポーネントをすべて備えた、縮小型のJVMである。Java Runtime Environmentライブラリ(libjvm.so) APIを実装し、必要なJARやネイティブライブラリはすべてGraalVMのものを再利用する。従来のJVMと同じく、Kotlinなど他のJVMベース言語の実行をサポートしている。
Javaで実装され、Javaを実行することができるので、Java on Truffleは基本的にはセルフホストJava、あるいはJava on Javaである。これはJava開発者にとって、JVMソースコードを読み、理解し、改善することが可能になるということで、JVMを調査し革新するという、興味深い機会を提供することになる。
Java on Truffleが提供する、注目すべき機能やメリットは次のようなものだ。
- 拡張されたHotSwap機能を活用して、デバッグセッション中に、メソッドやラムダの実行時修正やクラス修飾子への実行時アクセスを行うことができる。
- ホストJVMと異なるバージョンのJavaバイトコードを実行可能である。例えばPolyglot APIを経由することで、Java 8のみのライブラリをJava 11アプリケーション内部から起動できる。
- ホストJVMとTruffle上で動作するJavaアプリケーションを分離してサンドボックス化することで、信頼性の低いゲストコードの実行が可能になる。ここでのホストとゲストという名称は、Javaが実行されるレイヤの違いを区別するために使用されている用語で、Java on Truffleはゲストレイヤに相当する。
- JavaアプリケーションがJavaScriptやPythonなどの非JVM言語と直接的に相互運用して、同じメモリ空間内でデータを受け渡しすることが可能になる。
- Truffleフレームワークの提供する標準的ツールが活用できる。例えば、CPUサンプルプロファイリングツールを使用して、Javaアプリケーション内でCPU時間を要している部分を特定することが可能になる。
- Ahead-Of-Time(AOT)コンパイルによってビルドされたJavaネイティブイメージからJavaコードを動的にロードして実行し、EspressoのJITコンパイラを使用することが可能である。例えば、JenkinsなどのCI/CDアプリケーションはネイティブイメージとしてビルドしておいて、プラグインについては動的にロードする、という使用方法が可能になる。
これらの機能やメリットを示す目的で、一連のデモアプリケーションがGraalVMから提供されている。
ただし、Java on Truffleは試験的なコンポーネントであって、運用レベルに達していない点に注意が必要だ。また、Java on Truffleのウォームアップやピークパフォーマンスについては、今後のリリースで改善される期待はあるものの、今回の新リリースのピークパフォーマンスは、通常のJVMに比較すると数倍遅くなっている。今後のリリースで対応されると思われる、注意すべき制限を以下に挙げる。
- JVM Tool Interface(JVMTI)は未実装である。
-agentlib
および-agentpath
に相当するVMオプションがサポートされていない。 Java.lang.instrument
インターフェースは未実装である。-javaagnt
に相当するVMオプションがサポートされていない。- Java Management Extensions(JMX)の実装が不十分で、一部のメソッドは部分的なデータを返す場合がある。
今回のリリースには、Java on Truffle以外にも拡張が含まれている。例えば、ネイティブイメージバイナリでのJavaシリアライゼーションの使用が可能になった。シリアライゼーションの使用設定は、ネイティブイメージのビルドに先立って、Javaagent
で自動的に生成される。
今回のGraalVMのリリースでは、Ruby、Python、LLVMディストリビューションに関する互換性と実行時パフォーマンスについても、いくつかの改善が行われている。GraamVMのWebAssembly言語の実装であるGraalWasmも最適化されて、ウォームアップ時間とWebAssembly解析に関する全般的ピークパフォーマンスが向上した。
GraalVMコミュニティエディションのJavaバージョンがアップデートされて、OpenJDK 1.8.0_282およびOpenJDKバージョン 11.0.10がベースになった。同梱されるNode.jsディストリビューションも12.20.1にアップデートされている。
ツール面ではgu
が改良されて、バージョンアップデートが容易になった。Visual Studio Codeを使ったGraalVMアプリケーションの開発とデバッグを支援するGraalVM Extension Packも同時にリリースされている。