Java on Truffle

GraalVMを使用すると、JVMおよびネイティブ・イメージで、さらに現在はTruffleでJavaアプリケーションを正常に実行できます。Java on Truffleは、GraalVM上にTruffleインタプリタとしてビルドされたJava仮想マシン仕様(Java SE 8およびJava SE 11)の実装です。これは、VMのすべてのコア・コンポーネントを含み、Java Runtime Environmentライブラリ(libjvm.so)と同じAPIを実装し、GraalVMのすべてのJARおよびネイティブ・ライブラリを再利用する、縮小されたJava VMです。詳細は、「実装の詳細」を参照してください。この実装の背後にあるプロジェクト名はEspressoです。そのオープン・ソース・バージョンは、GitHubで入手できます。

Java on Truffle実行モードでは、Truffleフレームワーク(プログラミング言語のインタプリタを記述するためのオープンソース・ライブラリ)を使用して実装されたJavaバイトコード・インタプリタを介してJavaを実行します。JavaはGraalVMエコシステムの他の言語(JavaScript、Ruby、Python、R)と同じ原則に従って実行できるようになり、それらの言語と直接相互運用し、同じメモリー領域でデータを受け渡します。言語の完全な相互運用性に加えて、Java on Truffleでは次のことが可能です:

Java on TruffleはGraalVMの試験段階のテクノロジですが、Java Compatibility Kit (JCKまたはTCK for Java SE)にすでに合格しています。バージョン21.0.0の時点で使用できます。

Java on Truffleのインストール

Java on Truffleを実行するには、GraalVMをインストールする必要があります。Java on Truffleランタイムはデフォルトでは使用できませんが、GraalVMアップデータ・ツールを使用してGraalVMに簡単に追加できます。

GraalVM Community Editionのユーザーの場合、次のコマンドを実行してGitHubカタログからJava on Truffleをインストールします:

gu install espresso

インストール可能ファイルの名前espressoはプロジェクト・コード名であり、GraalVMでJavaコードを実行できる他の方法とのあいまいさを避けるために使用されます。

GraalVM Enterprise Editionのユーザーの場合は、Oracle GraalVMダウンロードからJava on Truffleをダウンロードします。オペレーティング・システムおよび基礎となるJava SEバージョンを考慮して適切なJARファイルをダウンロードしたら、次を使用してインストールします:

gu install -L espresso.jar

jvmランタイム・ライブラリがGRAALVM_HOME/lib/truffle/の場所にインストールされます。

Java on Truffleの実行

-truffleフラグを標準のjavaランチャに渡すことで、TruffleでJavaアプリケーションを実行できます。これは、-client JVMと-server JVMを切り替えた方法に似ています。

クラス・ファイルを実行するには:

java -truffle [options] class

JARファイルを実行するには:

java -truffle [options] --jar jarfile

Java 11ベースのGraalVMディストリビューションを使用すると、モジュール内のメイン・クラスからJavaアプリケーションを実行したり、単一のソースファイル・プログラムを実行することもできます:

java -truffle [options] -m module[/<mainclass>]
java -truffle [options] sourcefile

デフォルトでは、Java on Truffleは、GraalVMのJARおよびネイティブ・ライブラリすべてを再利用することでGraalVM内で実行されますが、クロスバージョンして、異なるJavaインストール・ディレクトリ(java.home)を指定することもできます。ホストJVMに関係なく、バージョンは自動的に切り替わります。

java -truffle --java.JavaHome=/path/to/java/home -version

パフォーマンスに関する考慮事項

Java on TruffleはGraalVMの試験段階のテクノロジで、現在、ピーク・パフォーマンスはHotSpotよりも2倍から3倍遅くなっています。

起動時間は通常のGraalVMのJust-in-Time (JIT)実行での速度にはまだ及びませんが、完全に機能するJava on Truffleランタイムの作成が完了したため、開発チームは現在パフォーマンスに重点を置いています。次のオプションをjava -truffleに渡すことで、引き続きパフォーマンスに影響を与えることができます:

--vm.XX:構文によって、基礎となるネイティブ・イメージVMにオプションが渡されることが確実化されます。-XX:構文を使用すると、VMは最初に、そのようなオプションがJava on Truffleランタイムにあるかどうかを確認します。存在しない場合、基礎となるネイティブ・イメージVMにこのオプションを適用しようとします。これは、両方のレベルで独立して設定できるMaxDirectMemorySizeなどのオプションで重要な場合があり、-XX:MaxDirectMemorySize=256MはTruffleで実行されるJavaプログラム(ゲストVM)で予約できるネイティブ・メモリーの量を制御しますが、--vm.XX:MaxDirectMemorySize=256Mはネイティブ・イメージ(ホストVM)で予約できるネイティブ・メモリーの量を制御します。

アプリケーションの実行の開始

コマンドラインから

このガイドでは、GraalVM Enterprise 21.2.0ディストリビューション(Java 11 for macOSに基づく)が使用されます。Java on Truffleが正常にインストールされたことを確認するには、そのバージョンを確認します:

java -truffle -version
java version "11.0.12" 2021-07-20 LTS
Java(TM) SE Runtime Environment GraalVM EE 21.2.0 (build 11.0.12+8-LTS-jvmci-21.2-b06)
Espresso 64-Bit VM GraalVM EE 21.2.0 (build 11-espresso-21.2.0, mixed mode)

このHelloWorld.javaの例を使用し、コンパイルしてコマンドラインから実行します:

public class HelloWorld {
  public static void main(String[] args) {
    System.out.println("Hello, World!");
  }
}
<graalvm>/bin/javac HelloWorld.java
<graalvm>/bin/java -truffle HelloWorld
HelloWorld.java!

現実的なアプリケーションとして、Spring PetClinic (Spring MVCおよびSpring Data JPAによるSpring Bootの使用をデモンストレーションするサンプルWebアプリケーション)を実行してみます。

  1. プロジェクトをクローニングし、プロジェクトのディレクトリに移動します:
    git clone https://github.com/spring-projects/spring-petclinic.git
    cd spring-petclinic
    
  2. JARファイルをビルドします(Spring PetClinicはMavenでビルドされます):
    ./mvnw package
    
  3. 次に、-truffleランタイムを選択することで、それをコマンドラインから実行します:
    java -truffle -jar target/spring-petclinic-2.4.2.jar
    
  4. アプリケーションが起動したら、localhost: 8000でアクセスします。

IDEから

IDEからTruffleでJavaプロジェクトを実行するには、Java on Truffle対応のGraalVMをプロジェクトのデフォルトのJDKとして設定する必要があります。たとえば、Intellij IDEAを使用してSpring PetClinicプロジェクトを実行するには、次のことが必要です:

1. 「File」→「Project Structure」→「Project」→「Project SDK」に移動します。ドロップダウンを展開し、「Add SDK」→「JDK」を押して、GraalVMをインストールしたフォルダを開きます。macOSユーザーの場合、JDKホームのパスは/Library/Java/JavaVirtualMachines/{graalvm}/Contents/Homeになります。名前を指定して「Apply」を押します。

2. ソースを生成し、プロジェクトのフォルダを更新します。Mavenサイドバーで、スピナー・アイコンが付いているフォルダをクリックします:

3. Java on Truffle実行モードを有効にします。メイン・メニューから、「Run」→「Run…」→「Edit Configurations」→「Environment」を選択します。「VM options」フィールドに-truffle -XX:+IgnoreUnrecognizedVMOptionsコマンドを入力し、「Apply」を押します。

まだサポートされていない-javaagent引数がIntellijによって自動的に追加されるため、-XX:+IgnoreUnrecognizedVMOptionsを指定する必要があります。

4. 「Run」を押します。

デバッグ

任意のIDEデバッガからJava on Truffleを実行しているアプリケーションをデバッグするために、特別な構成を行う必要はありません。たとえば、IntelliJ IDEAからのデバッガ・セッションの開始は実行構成に基づきます。デバッガを同じ環境内のJavaアプリケーションにアタッチするには、メイン・メニューで「Run」→「Debug…」→「Edit Configurations」に移動し、「Environment」を展開して、JREの値とVMオプションの値を確認します。GraalVMがプロジェクトのJREとして表示され、VMオプションには-truffle -XX:+IgnoreUnrecognizedVMOptionsが含まれている必要があります: -truffleでJava on Truffleを実行できるようにし、-XX:+IgnoreUnrecognizedVMOptionsはJava on TruffleランタイムでJavaエージェントのアタッチがまだサポートされていないことに対する一時的な回避策です。

Java on Truffleを使用すると、GraalVMエコシステム内の他の言語とのシームレスなJava相互運用が可能になります。強力なポリグロット・プログラムを作成するために、外部言語で記述されたコードをロードする方法、言語間でオブジェクトをエクスポートおよびインポートする方法、外部言語からJava-on-Truffleオブジェクトを使用する方法(その逆も同様)を学習するには、「Truffle言語との相互運用性」ガイドを参照してください。

実装アプローチ、プロジェクトの現在のステータスおよび既知の制限事項について学習するには、「実装の詳細」に進みます。

Eclipse IDE、Scala、その他の言語のREPLなどのいくつかの大規模なアプリケーションは、Java on Truffle実行モードですでに実行できます。「デモ・アプリケーション」のコレクションを参照することをお薦めします。

ご質問がある場合は、使用可能なFAQを確認するか、GraalVM Slack#espressoチャンネルで直接お問い合せください。