Oracle GraalVM Enterprise Editionスタート・ガイド

ここでは、GraalVM Enterpriseのダウンロードとインストール、基本的なアプリケーションの実行、および付随する機能のサポートの追加について説明します。さらに、GraalVM Enterpriseのポリグロット機能について学習し、JVMベースのアプリケーションのプラットフォーム固有のネイティブ実行可能ファイルをビルドする方法を確認します。

GraalVM Enterpriseを初めて使用する場合、または使用経験がほとんどない場合は、GraalVM Enterpriseの概要ページから始めることをお薦めします。ここには、GraalVM Enterpriseのアーキテクチャ、入手可能なディストリビューション、サポートされているプラットフォーム、ライセンスとサポート、コアと追加機能などに関する情報があります。

GraalVM Enterpriseがすでにインストールされ、使用経験がある場合は、このスタート・ガイドをスキップして、詳細なリファレンス・マニュアルに進むことができます。

GraalVM Enterpriseのダウンロード

Oracle GraalVM Enterprise Editionを取得するには、次の方法があります:

GraalVM Enterpriseのインストール

GraalVM Enterpriseをインストールして使用可能にするには数分かかります。オペレーティング・システムを選択し、特定のプラットフォームのインストール・ステップに進みます:

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

ここでは、デモ用に、Java 11に基づくGraalVM Enterpriseを使用します。

GraalVM Enterpriseのコア・ディストリビューションには、JVM、GraalVMコンパイラ、LLVMランタイムおよびJavaScriptランタイムが含まれます。GraalVM Enterpriseをダウンロードしてインストールすると、Java、JavaScriptおよびLLVMベースのアプリケーションを実行できます。

GraalVM Enterpriseの/binディレクトリは標準のJDKのディレクトリと似ていますが、追加のランチャおよびユーティリティのセットが含まれています:

デフォルトで提供されているランタイムのバージョンを確認します:

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)
Java HotSpot(TM) 64-Bit Server VM GraalVM EE 21.2.0 (build 11.0.12+8-LTS-jvmci-21.2-b06, mixed mode, sharing)

js -version
GraalVM JavaScript (GraalVM EE Native 21.2.0)

lli --version
LLVM 10.0.0 (GraalVM EE Native 21.2.0)

さらに、次に、Node.js、Ruby、R、PythonおよびWebAssemblyなど、オプションで使用可能な他のGraalVM Enterpriseランタイムを追加する方法についても説明します。

様々な言語のランタイム

Java

javaランチャは、GraalVM Enterpriseのデフォルト・コンパイラ(GraalVMコンパイラ)を使用してJVMを実行します。この典型的なHelloWorldクラスを次に示します:

public class HelloWorld {
  public static void main(String[] args) {
    System.out.println("Hello, World!");
  }
}

次のコマンドを実行してこのクラスをバイトコードにコンパイルし、実行します:

javac HelloWorld.java
java HelloWorld
Hello World!

GitHub上のGraalVMデモには、より大規模なJavaの例が数多くあります。GraalVMコンパイラの詳細は、Graalコンパイラを参照してください。Javaの実行の詳細は、JVM言語を参照してください。

JavaScriptおよびNode.js

GraalVM Enterpriseでは、REPLモードと、およびスクリプト・ファイルを直接実行する方法の両方で、プレーンJavaScriptコードを実行できます:

js
> 1 + 2
3

GraalVM Enterpriseでは、Node.jsアプリケーションの実行もサポートされます。Node.jsサポートはデフォルトではインストールされませんが、GraalVMアップデータを使用して簡単に追加できます。

gu install nodejs
node -v
v14.17.6

100,000を超えるnpmパッケージが定期的にテストされ、express、react、async、request、browserify、grunt、mocha、underscoreなどのモジュールを含むGraalVM Enterpriseと互換性があります。Node.jsモジュールをインストールするには、<graalvm>/binフォルダにあるnpm実行可能ファイルを使用します。これは、nodeとともにインストールされます。npmコマンドは、デフォルトのNode.jsコマンドと同等で、すべてのNode.js APIをサポートします。

npm installを使用して、colorsおよびansispanモジュールをインストールします。インストールしたモジュールは、アプリケーションから使用できます。

npm install colors ansispan

次のコード・スニペットを使用して、Node.jsモジュールをインストールしたディレクトリにapp.jsファイルとして保存します:

const http = require("http");
const span = require("ansispan");
require("colors");

http.createServer(function (request, response) {
    response.writeHead(200, {"Content-Type": "text/html"});
    response.end(span("Hello Graal.js!".green));
}).listen(8000, function() { console.log("Graal.js server running at http://127.0.0.1:8000/".red); });

setTimeout(function() { console.log("DONE!"); process.exit(); }, 2000);

nodeコマンドを使用して、GraalVM Enterpriseでapp.jsを実行します:

node app.js

Node.jsとの互換性に関する詳細なドキュメントおよび情報は、JavaScriptおよびNode.jsを参照してください。

LLVM言語

GraalVM Enterprise LLVMランタイムは、C/C++、Rust、およびLLVMビットコードにコンパイル可能なその他のプログラミング言語を実行できます。ネイティブ・プログラムは、clangなどのLLVMフロントエンドを使用してLLVMビットコードにコンパイルする必要があります。C/C++コードは、事前ビルドされたLLVMツールチェーンを介して、GraalVM Enterpriseに付属のclangを使用してLLVMビットコードにコンパイルできます。

LLVMツールチェーン・サポートを設定するには:

  1. プラグインをインストールします:
    gu install llvm-toolchain
    
  2. 利便性のために、LLVM_TOOLCHAIN変数をツールチェーンの場所にエクスポートします:
    export LLVM_TOOLCHAIN=$(lli --print-toolchain-path)
    

たとえば、次のCコードをhello.cという名前のファイルに入れます:

#include <stdio.h>

int main() {
    printf("Hello from GraalVM!\n");
    return 0;
}

次に、LLVMビットコードが埋め込まれた実行可能ファイルhellohello.cをコンパイルし、次のように実行します:

$LLVM_TOOLCHAIN/clang hello.c -o hello
lli hello

詳細なドキュメントおよびGraalVM EnterpriseでのLLVMビットコードの実行例は、LLVM言語を参照してください。

Python

GraalVM Enterpriseを使用すると、Python 3ランタイム環境でPythonアプリケーションを実行できます。このサポートはデフォルトでは使用できませんが、GraalVMアップデータ・ツールを使用してGraalVMに簡単に追加できます:

gu install python

インストールしたら、Pythonプログラムを実行できます:

graalpython
...
>>> 1 + 2
3
>>> exit()

GraalVMでのPythonサポートのその他の例および詳細は、Pythonのリファレンス・マニュアルを参照してください。

Ruby

GraalVM Enterpriseは、RubyGemsやRuby Bundlerなどとの対話を可能にするgemコマンドを含む、高パフォーマンスのRubyランタイム環境を提供します。Rubyランタイムは、デフォルトではGraalVMで使用できませんが、GraalVMアップデータ・ツールを使用して簡単に追加できます:

gu install ruby

インストールすると、rubygemirbrakerdocriなどのRubyランチャでRubyプログラムを実行できるようになります:

ruby [options] program.rb

GraalVM Rubyランタイム環境では、Rubyの標準実装と同じオプションが使用されますが、いくつかの追加があります。たとえば:

gem install chunky_png
ruby -r chunky_png -e "puts ChunkyPNG::Color.to_hex(ChunkyPNG::Color('mintcream @ 0.5'))"
#f5fffa80

その他の例および詳細なドキュメントは、Rubyのリファレンス・マニュアルを参照してください。

R

GraalVM Enterpriseは、Rプログラムを直接またはREPLモードで実行するためのGNU互換環境を提供します。R言語サポートはデフォルトでは使用できませんが、GraalVMアップデータ・ツールを使用してGraalVM Enterpriseに追加できます:

gu install R

インストール後、Rスクリプトを実行してR REPLを使用できます:

R
R version 4.0.3 (FastR)
...

> 1 + 1
[1] 2

その他の例および詳細なドキュメントは、Rのリファレンス・マニュアルを参照してください。

WebAssembly

GraalVM Enterpriseを使用すると、WebAssemblyにコンパイルされたプログラムを実行できます。このサポートはデフォルトでは使用できませんが、GraalVMアップデータ・ツールを使用してGraalVMに追加できます:

gu install wasm

その後、コンパイルされたWebAssemblyバイナリ・コードを実行できるwasmランチャが使用可能になります。

たとえば、floyd.cという名前のファイルに次のCプログラムを入れます:

#include <stdio.h>

int main() {
  int number = 1;
  int rows = 10;
  for (int i = 1; i <= rows; i++) {
    for (int j = 1; j <= i; j++) {
      printf("%d ", number);
      ++number;
    }
    printf(".\n");
  }
  return 0;
}

最新のEmscriptenコンパイラのフロントエンド・バージョンを使用してコンパイルします。現在の作業ディレクトリにスタンドアロンfloyd.wasmファイルが生成されます:

emcc -o floyd.wasm floyd.c

次に、コンパイルしたWebAssemblyバイナリをGraalVMで次のように実行できます:

wasm --Builtins=wasi_snapshot_preview1 floyd.wasm

詳細は、WebAssemblyのリファレンス・マニュアルを参照してください。

ネイティブ・イメージ

GraalVM Enterpriseを使用すると、Javaバイトコードをプラットフォーム固有の自己完結型のネイティブ実行可能ファイルにコンパイルして、アプリケーションの起動を高速化し、フットプリントを縮小できます。ネイティブ・イメージ機能はデフォルトでは使用できませんが、GraalVMアップデータ・ツールを使用して簡単にインストールできます:

gu install native-image

前述のHelloWorldの例を使用して、ネイティブ実行可能ファイルの生成方法を示します:

public class HelloWorld {
  public static void main(String[] args) {
    System.out.println("Hello, World!");
  }
}

ノート: コンパイルについては、native-imageはローカル・ツールチェーンに依存します。システムが前提条件を満たしていることを確認します。

HelloWorld.javaをバイトコードにコンパイルし、ネイティブ実行可能ファイルをビルドします:

javac HelloWorld.java
native-image HelloWorld

最後のコマンドは、現在の作業ディレクトリにhelloworldという名前の実行可能ファイルを生成します。これを呼び出すと、ネイティブにコンパイルされたHelloWorldクラスのコードが次のように実行されます:

./helloworld
Hello, World!

この革新的なテクノロジの詳細は、ネイティブ・イメージのリファレンス・マニュアルを参照してください。

ネイティブ・イメージのポリグロット機能

GraalVM Enterpriseでは、ネイティブ実行可能ファイルをビルドするときにポリグロット機能を使用できます。JavaScriptコードを埋め込むJSON pretty-printer Javaプログラムの例を次に示します:

import java.io.*;
import java.util.stream.*;
import org.graalvm.polyglot.*;

public class PrettyPrintJSON {
  public static void main(String[] args) throws java.io.IOException {
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    String input = reader.lines()
    .collect(Collectors.joining(System.lineSeparator()));
    try (Context context = Context.create("js")) {
      Value parse = context.eval("js", "JSON.parse");
      Value stringify = context.eval("js", "JSON.stringify");
      Value result = stringify.execute(parse.execute(input), null, 2);
      System.out.println(result.asString());
    }
  }
}

これをコンパイルして、ネイティブ実行可能ファイルをビルドします。--language:js引数により、生成されたイメージでJavaScriptが使用可能になります:

javac PrettyPrintJSON.java
native-image --language:js --initialize-at-build-time PrettyPrintJSON

PrettyPrintJSONクラスのみでなくJavaScriptもビルドするため、ネイティブ実行可能ファイルの生成には数分かかります。また、特にこのケースのようにTruffle言語実装フレームワークを使用してネイティブ実行可能ファイルをビルドする場合は、ビルドに大量の物理メモリーが必要になります。

生成された実行可能ファイルでJSON整形出力を実行できるようになりました:

./prettyprintjson <<EOF
{"GraalVM":{"description":"Language Abstraction Platform","supports":["combining languages","embedding languages","creating native images"],"languages": ["Java","JavaScript","Node.js", "Python", "Ruby","R","LLVM"]}}
EOF

ネイティブ実行可能ファイルからのJSON出力は次のとおりです:

{
  "GraalVM": {
    "description": "Language Abstraction Platform",
    "supports": [
      "combining languages",
      "embedding languages",
      "creating native images"
    ],
    "languages": [
      "Java",
      "JavaScript",
      "Node.js",
      "Python",
      "Ruby",
      "R",
      "LLVM"
    ]
  }
}

ネイティブ実行可能ファイルは、JVMで同じコードを直接実行するよりもはるかに高速に実行されます:

time bin/java PrettyPrintJSON < test.json > /dev/null
real	0m1.101s
user	0m2.471s
sys	0m0.237s

time ./prettyprintjson < test.json > /dev/null
real	0m0.037s
user	0m0.015s
sys	0m0.016s

言語の結合

GraalVM Enterpriseでは、あるプログラミング言語を別のプログラミング言語からコールし、それらの間でデータを交換できます。相互運用性を有効にするために、GraalVM Enterpriseには--polyglotフラグが用意されています。

たとえば、js --jvm --polyglot example.jsを実行すると、example.jsがポリグロット・コンテキストで実行されます。プログラムがサポートされている他の言語のコードをコールすると、GraalVM Enterpriseはexample.jsアプリケーションと同じランタイムでそのコードを実行します。多言語アプリケーションの実行の詳細は、「ポリグロット・プログラミング」を参照してください。

新規ユーザー

このガイドは、主にGraalVM Enterpriseを初めて使用するユーザー、またはGraalVM Enterpriseに関する知識はあるが使用経験がほとんどないユーザーを対象としているため、より複雑なサンプル・アプリケーションを調べることを検討してください。

Oracle Cloudユーザー

クラウド・ワークロードにGraalVM Enterpriseを検討しているOracle Cloudユーザーは、OCIでのGraalVM Enterpriseを参照することをお薦めします。このページでは、Oracle Cloud Infrastructure仮想マシン・コンピュート・インスタンスでのGraalVM Enterpriseの使用に焦点を当てています。

上級ユーザー

特定の言語のGraalVM Enterpriseサポートに主に関心がある場合、またはGraalVM Enterpriseの様々な機能のより詳細な情報が必要な場合は、リファレンス・マニュアルを参照してください。

GraalVM Enterpriseが提供するツールのサポートを探している場合は、デバッグおよびモニタリング・ツールに進んでください。

GraalVM Enterpriseを将来の言語またはツール実装のプラットフォームとして検討している場合は、「プラットフォームとしてのGraalVM Enterprise」に移動してください。

GraalVM Enterpriseのセキュリティ・モデルの詳細は「セキュリティ・ガイド」、リッチAPIドキュメントは「GraalVM SDK Javadoc」を参照してください。