[WASM] CheerpJ 3.0を使ってブラウザでJavaアプリを動かす [アプレット]

2024.02.08

Introduction

つい先日、CheerpjJ 3.0というブラウザでJavaアプリを実行可能にする
コンパイラ/ランタイムがリリースされました

これを使えば古のアプレットやSwingで作ったJavaアプリケーションが
最新ブラウザでpluginなしで動きます。

また、ライブラリ用のjarファイルもそのまま動かすことができるので、
本稿ではJavaライブラリをブラウザ上で使ってみます。

CheerpjJ 3.0?

こことかで紹介されてますが、CheerpjJ 3.0について簡単に解説します。

CheerpJ 3.0は、Leaning Technologiesによって開発された、
ブラウザで動作するWASMベースのJavaランタイムです。 JavaバイトコードをJavascriptにJIT compileして実行できます。
何かを追加でインストールしたりする必要はありません。

現在はJava8をサポートしており、
2024年後半には、Java 11 以降をサポートする予定とのことです。

Java8が動くので昔つくったアプレットも動くし、
IntelliJ IDEA 2019 とかMineCraftとかも動くみたいです。
そして、AWTやSwingをつかったアプリも動きますし、jarライブラリも
そのままjavascriptから実行可能です。

Environments

  • MacBook Pro (13-inch, M1, 2020)
  • OS : MacOS 13.5.2
  • sdkman : script: 5.18.2,native: 0.4.6

Try

Apache Commons Langをブラウザで動かす

CheerpJ 3.0ではjarライブラリも直接loadして使うことができます。
そこで、昔たいへんお世話になったCommons Langを使ってみましょう。
ここからjarファイルがダウンロードできます。

javapでサポートclassバージョンを確認。
52(Java8)なので動きます。

% javap -verbose -cp ./commons-lang3-3.14.0.jar org.apache.commons.lang3.text.StrBuilder | grep "major"
  major version: 52

jarファイルと同じ場所にindex.htmlファイルを作成して
下記のように記述します。

<!doctype html>
<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <title>CheerpJ test</title>
    <script src="https://cjrtnc.leaningtech.com/3.0/cj3loader.js"></script>
  </head>
  <body>
    <script>
      (async function () {
        await cheerpjInit();
        const cj = await cheerpjRunLibrary("/app/commons-lang3-3.14.0.jar");
        const StrBuilder = await cj.org.apache.commons.lang3.text.StrBuilder;
        var obj = await new StrBuilder();
        await obj.appendln("Long time no see, Apache Commons Lang!");
        var result = await obj.toString();
        console.log("result string: " + result);
      })();
    </script>
    hello commons lang
  </body>
</html>

cj3loader.jsをscriptタグで指定し、
cheerpjRunLibraryでjarを指定します。(/appが大事)
あとは実際にクラスをインスタンスしてメソッドを呼んでます。

httpサーバを起動してブラウザでアクセスしてみると、
コンソールにCommons Langの実行結果メッセージが表示されます。

% npx http-server -p 8080

自分でjarを作成して動かす

まったくメリットはないのですが、自分で作成したjarもブラウザで動かしてみましょう。
現状の対応はJava8なので、SDKMANでインストールします。

% sdk install java 8.0.402-zulu

これより後のJavaを使うと、たぶん実行時に
java.lang.UnsupportedClassVersionError
がでます。

hogeディレクトリを作って、
StringProviderクラスを作成します。

//StringProvider.java
package hoge;

public class StringProvider {
    public String getString() {
        return "Hello my jar file";
    }
}

先程のindex.htmlを下記のように修正。

const cj = await cheerpjRunLibrary("/app/stringprovider.jar");
const StringProvider = await cj.hoge.StringProvider;
var obj = await new StringProvider();
var result = await obj.getString();
console.log("result : " + result);

コンパイルしてjarコマンドでjarファイルを作成します。
jarなんて使ったの何年ぶりだろう。

% javac hoge/StringProvider.java
% jar cvf stringprovider.jar hoge/StringProvider.class

javapでバージョンを確認。

javap -verbose -cp ./stringprovider.jar hoge.StringProvider | grep "major"
major version: 52

ブラウザからアクセスしてみると、ちゃんとアクセスできてます。

Summary

昔のJavaコードがそのままブラウザで動くとか、
かなりすごいですね。
Javaアプリ、アプレット、jarライブラリと動きますし、
今後サポートバージョンも広がっていくので、
さらに使い勝手がよくなりそうです。

References