VSCodeでGraalVMを動かす(Java/NodeJS編)

# 初めに
- VSCodeのGraalVM拡張を用いて以下のプログラムを動作させた話
    - Java (単純なHelloWorldと、JavaからJSのコードを呼び出す2パターン)
    - node.js (シンプルなWebアプリケーションを起動)
- 実行環境は以下の通り
    - Windows 10
    - GraalVM CE 22.3.1
    - VSCode 1.76.2
- 誤り等あれば、ご指摘いただけますと幸いです
 
# 環境構築
## 1. GraalVMをインストールする
- [Installation on Windows Platforms](https://www.graalvm.org/latest/docs/getting-started/windows/)からGraalVMをインストールする
   - 以降、C:\Program Files\graalvm に展開したものとして説明する

- インストール後、環境変数PATHとJAVA_HOMEを以下の通り設定する
   |環境変数|値|
   |--|--|
   | PATH | C:\Program Files\graalvm\bin を追加 |
   | JAVA_HOME | C:\Program Files\graalvm |

## 2. GraalVM Tools for Java Extension をインストール
- VSCodeのExtensionsからGraalVM Tools for Java Extensionを選択し、インストールする
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361228/eb1f8114-f058-86d5-7d0e-3d8d62a83a61.png" width=80%>
- インストール後、VSCodeのActive bar に Gr が表示される。クリックすると、自分の環境のGraalVMのコンポーネントが確認できる
        <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361228/85d14a3c-0734-d22a-005e-48af6ebe6c21.png" width=40%>

## 3. デフォルトのJavaの設定
- VSCode の View -> Command Palette から`GraalVM: Set Active GraalVM Installation`と入力し、インストールしたGraalVMを選択する
- 設定画面から、以下の2つを選択
    - Set as JAVA for Terminal options (JAVA_HOME in termainal.integrated.env.osx) 
    - Set as JAVA for Terminal options (PATH in termainal.integrated.env.osx)
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361228/0bfbc7b8-3d3c-6e71-9255-203a72c4e2f7.png" width=70%>

## 4. 環境確認 (Java)
- VSCodeのTERMINALに`java --version`と入力。GraalVMのJVMが表示される事を確認
    ```
    openjdk 17.0.6 2023-01-17
    OpenJDK Runtime Environment GraalVM CE 22.3.1 (build 17.0.6+10-jvmci-22.3-b13)
    OpenJDK 64-Bit Server VM GraalVM CE 22.3.1 (build 17.0.6+10-jvmci-22.3-b13, mixed mode, sharing
    ```

## 5. 環境確認 (node.js)
- VSCodeのTERMINALに`node --version:graalvm `と入力。GraalVMの情報が表示されることを確認
    ```
    GraalVM CE Native Polyglot Engine Version 22.3.1
    Java Version 17.0.6
    Java VM Version GraalVM 22.3.1 Java 17 CE
    GraalVM Home C:\Program Files\graalvm
      Installed Languages:
        JavaScript version 22.3.1
    ```

## 6. ワークスペースの作成
- `C:\dev\GraalVMSample`フォルダを作成し、VSCodeのワークスペースとして開いておく

# Javaを動かす1 (Hello world)

## 1. サンプルファイル作成
- `VMSample`フォルダ直下に`Sample.java`を作成する
    ```java:Sample.java
    public class Sample {
    	public static void main(String[] args) {
    		System.out.println("Hello world");
            System.out.println("java.vm.vendor = " + System.getProperty("java.vm.vendor"));
    	}
    }
    ```

## 2. 起動ファイルの設定
- VSCodeのデバッグビューから`create a launch.json file`をクリックする。
![image5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361228/ae41acfc-29af-cf2c-d22a-0425eab5f01b.png)

- `launch.json`がVMSampleフォルダに作成される
    ```json:launch.json
    {
        "version": "0.2.0",
        "configurations": [
            {
              "type": "java",
              "name": "Launch Java",
              "request": "launch",
              "mainClass": "${file}"
            }
          ]
    }
    ```

## 3. 実行
- デバッグビューからRun and Debug -> Launch Java を実行する。
-  TERMINALに以下のように表示されればOK
    ```
    Hello world
    java.vm.vendor = GraalVM Community
    ```

# Javaを動かす2 (JavaからJSを実行する)

## 1. サンプルファイルの修正
- VMSampleフォルダの`Sample.java`を以下のように修正する。
- `org.graalvm.polyglot.Context#create`で、多言語の実行コンテキストを作成する。
    ```diff_java:Sample.java
    + import org.graalvm.polyglot.*;
    public class Sample {
    	public static void main(String[] args) {
    +        Context polyglot = Context.create();
    +       Value array = polyglot.eval("js", "[1,2,42,4]");
    +       int result = array.getArrayElement(2).asInt();
    		System.out.println("Hello java on GraalVM");
    		System.out.println("java.vm.vendor = " + System.getProperty("java.vm.vendor"));
    +       System.out.println("Array:" + array + "'s 2nd element is " + result);
        }
    }
    ```

## 2. 実行
- デバッグビューからRun and Debug -> Launch Java を実行する。Javascriptの配列処理が行われている
    ```
    Hello java on GraalVM
    java.vm.vendor = GraalVM Community
    Array:(4)[1, 2, 42, 4]'s 2nd element is 42
    ```

# node.jsを動かす

## 1. サンプルファイル作成
- VMSampleフォルダ直下に`App.js`を作成する
    ```js:App.js
    http
      .createServer(function (request, response) {
        response.writeHead(200, { "Content-Type": "text/html" });
        response.end("Hello Graal.js!");
      })
      .listen(8000, function () {
        console.log("Graal.js server running at http://127.0.0.1:8000/");
      });
    ```
## 2. 起動ファイルの設定
- `launch.json`にNodeJSの起動設定を追加する
    ```diff_json:launch.json
    {
        "version": "0.2.0",
        "configurations": [
            {
              "type": "java",
              "name": "Launch Java",
              "request": "launch",
              "mainClass": "${file}"
           },
           {
              "type": "graalvm",
              "request": "launch",
              "name": "Launch Node App",
              "outputCapture": "std",
              "protocol": "chromeDevTools",
              "program": "${workspaceFolder}/App.js"
            }
          ]
    }
    ```

## 3. 実行
- デバッグビューからRun and Debug -> Launch Node App を実行する。
- 実行後、TERMINALに以下のように表示され、http://127.0.0.1:8000/にアクセスできればOK
    ```
    Hello js on Graalvm
    Graal.js server running at http://127.0.0.1:8000/
    ```

# 引用
https://www.graalvm.org/latest/tools/vscode/graalvm-extension/