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 VMとは別のコンテキストでJavaバイトコードを実行します。
- Java 8、Java 11、Java 17ゲストJVMのいずれかを実行し、GraalVMのポリグロットAPIを使用して、Java 11アプリケーションにJava 8のコンテキストなどを埋め込むことができます
- 以前はJavaで使用できなかった、Truffleフレームワークで提供されるツールのスタック全体を活用します。
- ホストJava VMとTruffleで実行されるJavaプログラムの分離が強化されたため、信頼性の低いゲスト・コードを実行できます。
- 動的にロードされるバイトコードを許可しながら、ネイティブ実行可能ファイルのコンテキストで実行します。
Java on Truffleは、Java Compatibility Kit (JCKまたはTCK for Java SE)に合格しています。
Java on Truffleのインストール
Java on Truffleランタイムはデフォルトでは使用できませんが、GraalVMアップデータ・ツールを使用してGraalVMに簡単に追加できます。
gu install espresso
インストール可能ファイルの名前espresso
はプロジェクト・コード名であり、GraalVMでJavaコードを実行できる他の方法とのあいまいさを避けるために使用されます。jvm
ランタイム・ライブラリが$JAVA_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
パフォーマンスに関する考慮事項
起動時間は通常のGraalVMのJust-in-Time (JIT)実行での速度にはまだ及びませんが、完全に機能するJava on Truffleランタイムの作成が完了したため、開発チームは現在パフォーマンスに重点を置いています。次のオプションをjava -truffle
に渡すことで、引き続きパフォーマンスに影響を与えることができます:
--engine.MultiTier=true
: 複数層のコンパイルを有効にします。--engine.Inlining=false
と--java.InlineFieldAccessors=true
の組合せ: パフォーマンスが低下するかわりに、コンパイルが高速になります。
--vm.XX:
構文によって、基礎となるネイティブ・イメージVMにオプションが渡されることが確実化されます。-XX:
構文を使用すると、VMは最初に、そのようなオプションがJava on Truffleランタイムにあるかどうかを確認します。存在しない場合、基礎となるネイティブ・イメージVMにこのオプションを適用しようとします。これは、両方のレベルで独立して設定できるMaxDirectMemorySize
などのオプションで重要な場合があり、-XX:MaxDirectMemorySize=256M
はTruffleで実行されるJavaプログラム(ゲストVM)で予約できるネイティブ・メモリーの量を制御しますが、--vm.XX:MaxDirectMemorySize=256M
はネイティブ・イメージ(ホストVM)で予約できるネイティブ・メモリーの量を制御します。
アプリケーションの実行の開始
コマンドラインから
Java on Truffleが正常にインストールされたことを確認するには、そのバージョンを確認します:
java -truffle -version
このHelloWorld.java
の例を使用し、コンパイルしてコマンドラインから実行します:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
$JAVA_HOME/bin/javac HelloWorld.java
$JAVA_HOME/bin/java -truffle HelloWorld
HelloWorld.java!
現実的なアプリケーションとして、Spring PetClinic (Spring MVCおよびSpring Data JPAによるSpring Bootの使用をデモンストレーションするサンプルWebアプリケーション)を実行してみます。
- プロジェクトをクローニングし、プロジェクトのディレクトリに移動します:
git clone https://github.com/spring-projects/spring-petclinic.git cd spring-petclinic
- JARファイルをビルドします(Spring PetClinicはMavenでビルドされます):
./mvnw package
- 次に、
-truffle
ランタイムを選択することで、それをコマンドラインから実行します:java -truffle -jar target/spring-petclinic-<version>-SNAPSHOT.jar
- アプリケーションが起動したら、localhost: 8000でアクセスします。
IDEから
IDEからTruffleでJavaプロジェクトを実行するには、Java on Truffle対応のGraalVMをプロジェクトのデフォルトのJDKとして設定する必要があります。たとえば、Intellij IDEAを使用してSpring PetClinicプロジェクトを実行するには、次のことが必要です:
1. 「File」、「Project Structure」の順に移動します。「Project」、「Project SDK」の順にクリックします。ドロップダウンを展開し、「Add 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チャンネルで直接お問い合せください。