TeaVMを使ってブラウザ上でJavaを実行する方法

# 1. WebAssemblyチュートリアル

WebAssemblyは、JavaScriptをブラウザベースの機能を超えて押し出す、非常に複雑で圧倒的に洗練された計算を実行するために作られました。JavaScriptが助けを必要とするたびに呼び出されます。

WebAssemblyのロジックは、WebAssembly仮想命令セットファイルにコンパイルできる任意の言語でコーディングできます。つまり、WebAssemblyの助けを借りて、ブラウザはScala、C/C++、Rust、GoLang、Kotlin、Clojure、C#、そして最も重要なJavaなど、さまざまな言語で書かれたコードを実行できるようになりました。

# 2. W3C、WebAssembly（WASM）

さらに、WebAssembly（WASM）は、Chrome、Safari、Firefox、Edgeを含むすべての主要なブラウザでサポートされているW3C標準です。それを使用するためにサードパーティのツールをインストールする必要はありません。WebAssemblyを使用すると、Mozillaプラグインをインストールしたり、Javaアプレットと戦ったりすることなく、ブラウザでJavaを実行できます。

必要なのは、JavaコードをWASMバイナリファイルにコンパイルすることだけで、ブラウザが残りの部分を処理します。

# 3. ブラウザでWebAssemblyをJavaを実行する手順

ブラウザでWebAssemblyを使用してJavaを実行するための基本的な手順は次のとおりです：

1. WebAssembly互換のコンパイラとAPIを使用してJavaコードを構築します。
2. ビジネスロジックを含むJavaメソッドを書きます。
3. JavaScriptと対話するためのJavaコードにネイティブメソッド参照を追加します。
4. Javaプログラムから返されたデータを処理するJavaScriptメソッドを書きます。
5. WebAssembly APIを使用してJavaScriptからJavaコードを呼び出します。
6. JavaコードをWebAssembly WASMファイルにコンパイルします。
7. HTMLとWASMファイルを一緒にパッケージ化してデプロイし、Webページを表示します。

# 4. WebAssembly互換のコンパイラとAPI

ブラウザでJavaを実行するためには、コードをWebAssemblyバイナリファイルにコンパイルする必要があります。これを助けるためのいくつかのAPIがあります：

- [CheerpJ](https://leaningtech.com/cheerpj/)
- [JWebAssembly](https://github.com/i-net-software/JWebAssembly)
- [TeaVM](https://teavm.org/)

今回はTeaVMを使用します。

TeaVMのWebAssembly機能をブラウザで利用するためには、Maven設定にWebAssembly用のteavm-classlib Java APIと、JavaをWASMにコンパイルするためのteavm-maven-pluginが必要です。

また、TeaVMの詳細な使い方については、公式サイトの[Getting Startedページ](https://teavm.org/docs/intro/getting-started.html)を参照してください。なお、TeaVMの初心者が[GitHub](https://github.com/konsoletyper/teavm)から直接最新のソースコードを使用するのは推奨されません。安定性の問題やコンパイルエラー、テストの実行時間が長引く可能性があるためです。

初めての方は、Mavenを用いてTeaVMプロジェクトを作成することを推奨します。プロジェクトの作成はコマンドラインで指定のコマンドを実行します。作成後に新しいディレクトリに移動し、プロジェクトをビルドすると、WebAssemblyを含むブラウザで実行可能なWebアプリケーションが生成されます。

```sh
mvn -DarchetypeCatalog=local -DarchetypeGroupId=org.teavm -DarchetypeArtifactId=teavm-maven-webapp -DarchetypeVersion=0.8.1 archetype:generate
```

# 5. TeaVM Javaコード

このJavaコードは、TeaVMを使ってWebAssembly(WASM)で実行されることを想定しています。具体的には、WebAssemblyがブラウザ上で実行される際に、新しい <div> 要素をDOMに追加し、その中に "TeaVM generated element" というテキストノードを作成します。

```java:Client.java
package jp.livlog;

import org.teavm.jso.dom.html.HTMLDocument;

public class Client {
    public static void main(String[] args) {
        var document = HTMLDocument.current();
        var div = document.createElement("div");
        div.appendChild(document.createTextNode("TeaVM generated element"));
        document.getBody().appendChild(div);
    }
}
```

Javaアプリケーションをビルドするためにmvn packageコマンドを実行すると、このJavaソースコードはcomplexlogic.wasmという名前のファイルにコンパイルされ、/wasmという名前のサブフォルダに配置されます。これらの設定はpom.xmlの設定を通じて変更できます。

# 6. TeaVMを使用したWebページの全コード

Number Guesser Game HTMLページの全コードは以下の通りです：

```html
<!DOCTYPE html>
<html>
  <head>
    <title>Main page</title>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
    <script type="text/javascript" charset="utf-8" src="teavm/classes.js"></script>
  </head>
  <body onload="main()">
    <!-- TODO: add HTML content -->
  </body>
</html>
```

# 7. TeaVMデプロイメント

アプリケーションをデプロイメントの準備をするためには、Maven packageコマンドを実行します：

```bash
mvn package
```

Maven POMは、packageコマンドがデプロイメントのための2つのファイルを生成するように設定されています：

1. Webページを表すindex.html
2. /teavmサブフォルダにあるclasses.jsという名前のファイル

# 8. TeaVMアプリケーションの実行

ビルドされたファイルは `target/(アーティアクトID)-(バージョン)` というフォルダに作成されます。

versionとpackageを指定しない場合、 `target/(アーティアクトID)-1.0-SNAPSHOT` というフォルダに生成されていると思います。

フォルダ内のindex.htmlをブラウザで読み込むと、次のような表示がされればビルドは成功しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20464/0c50569b-75f3-06d9-570b-b697cfc861f5.png)


# 9. TeaVMチュートリアルコードはGitHubにあります

このブラウザでのTeaVMのソースコードはGitHubに置いてあります。


https://github.com/blue-islands/teavm-samples-hello


## ※参考

https://www.theserverside.com/blog/Coffee-Talk-Java-News-Stories-and-Opinions/java-in-the-browser-webassembly-tutorial-wasm-teavm-html-javascript

https://qiita.com/sio29/items/b7ed0490eb935ac1aa7d