Webswing:インストール不要でJavaデスクトップアプリをブラウザで直接実行する

Virtualization tutorial - IT technology blog
Virtualization tutorial - IT technology blog

よくある問題:誰もインストールしたがらないJavaデスクトップアプリ

以前、あるクライアントからチームに難題が持ち込まれた。彼らには古いJavaデスクトップアプリ(Swing GUI)があり、Windows上では問題なく動いていたが、50人のメンバー全員がブラウザから使いたい、JREのインストールも各端末へのITサポートも不要で、という要望だった。Webアプリとして書き直す?6か月かかる上に予算もない。TeamViewerやAnyDeskを使う?50人が同時接続するとなるとスケールが大変すぎる。

そこで初めて出会ったのがWebswingだ。そして数時間でまさにその問題を解決してくれた。

アプリケーション仮想化とは?Webswingはどこに位置するのか

インストール手順に入る前に、全体像を少し整理しておこう。アプリケーション仮想化の基本的な考え方はシンプルだ:アプリはサーバー側で動き、クライアントはそのUIをストリーミングで受け取るだけ。操作もできるし画面も見えるが、端末には何もインストールされない。

WebswingはそのアイデアをJava専用に実装したものだ。Swing/JavaFXアプリ全体がサーバー上で動作し、レンダリング結果がHTML5 canvasとしてブラウザにストリーミングされる。マウスクリックやキー入力はブラウザがキャプチャしてサーバーへ送信し、サーバーが処理して新しいフレームを返す。最大のポイントは:元のJavaアプリに一切変更不要ということだ。アプリ自身はブラウザ上で動いていることを全く知らない。

CitrixやRDSなどのソリューションとの違い:

  • Windows Serverライセンス不要:WebswingはLinux上でも問題なく動作する
  • クライアントプラグイン不要:モダンブラウザ(Chrome、Firefox、Edge)だけあればよい
  • ネイティブHTTP/WebSocket:nginxでリバースプロキシが簡単、既存インフラへの統合も容易
  • セッション分離:ユーザーごとに独立したJVMが起動するため、互いに影響しない

私のホームラボ――Proxmox VEで12台のVMとコンテナを管理し、本番投入前に何でも試せるプレイグラウンド――では、WebswingはUbuntu 22.04のLXCコンテナ上で動かしている。セットアップして動作確認が取れてから、クライアント環境に展開した。

Webswingのインストールと設定

環境の準備

WebswingにはJava 11以上が必要だ。ここではUbuntu 22.04を使用する:

sudo apt update
sudo apt install -y openjdk-17-jdk wget unzip
java -version
# openjdk version "17.0.x"

公式サイトからWebswingをダウンロードする。Community Editionは非商用目的であれば無料で利用できる:

# ダウンロード前にwebswing.orgで最新バージョンを確認すること
wget https://webswing.org/download/webswing-23.2.zip -O webswing.zip
unzip webswing.zip -d /opt/
mv /opt/webswing-* /opt/webswing

Webswingの初回起動

cd /opt/webswing
./webswing.sh

Webswingはポート8080で起動する。http://localhost:8080にアクセスすると、SwingSet3やJFreeChartなどのデモアプリが同梱されたAdmin Consoleが表示される。デフォルトの認証情報はadmin/adminだ――本番環境で恥をかきたくなければすぐに変更すること。

Javaアプリケーションの設定

inventory-app.jarというJARファイルがある場合を例に挙げる。/opt/webswing/webswing.configにエントリを追加する:

{
  "path": "inventory",
  "name": "Inventory Management",
  "mainClass": "com.company.inventory.MainApp",
  "classPathEntries": [
    "/opt/apps/inventory-app.jar",
    "/opt/apps/lib/*.jar"
  ],
  "vmArgs": "-Xmx512m -Dfile.encoding=UTF-8",
  "maxClients": 10,
  "isolatedFs": true
}

設定を保存したらWebswingを再起動する。アプリはhttp://localhost:8080/inventoryに表示されるようになる。

nginxによるリバースプロキシ

本番環境ではポート8080を直接公開してはいけない。nginxの設定は以下の通りだ:

server {
    listen 443 ssl;
    server_name apps.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/apps.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/apps.yourdomain.com/privkey.pem;

    location / {
        proxy_pass http://localhost:8080;
        proxy_http_version 1.1;

        # WebSocketサポート — Webswingに必須
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # 長時間セッション向けにタイムアウトを延長
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
    }
}

UpgradeヘッダーとConnection: upgradeは必須だ――これがないとWebSocketが接続できず、アプリが描画されない。最初にこのミスをやらかして、デバッグに30分近く費やした。

WebswingをSystemdサービスとして実行する

sudo tee /etc/systemd/system/webswing.service << 'EOF'
[Unit]
Description=Webswing Application Server
After=network.target

[Service]
Type=simple
User=webswing
WorkingDirectory=/opt/webswing
ExecStart=/opt/webswing/webswing.sh
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF

# 専用ユーザーを作成する — rootでサービスを実行してはいけない
sudo useradd -r -s /bin/false webswing
sudo chown -R webswing:webswing /opt/webswing

sudo systemctl daemon-reload
sudo systemctl enable --now webswing
sudo systemctl status webswing

本番環境投入前に検討すべきこと

RAMの計画

ユーザーセッションごとに独立したJVMが起動する。アプリが256MBのヒープを必要とする場合、10人の同時ユーザーではOSオーバーヘッドを除いても2.5GB以上のRAMが消費される。サーバーのRAMに合わせてmaxClientsを適切に設定し、jstatや監視スタックがあればGrafanaでモニタリングすること。

ファイルシステムの分離

isolatedFs: trueを有効にすると、各セッションに独立したホームディレクトリが割り当てられ、ユーザー間でファイルが読み取られるリスクを防げる。ファイルの保存・オープン機能があるアプリでは特に重要だ――この設定を忘れたせいでセッション間でデータが混在してしまったケースを実際に見たことがある。

クリップボードとファイル転送

テキストのコピー&ペーストやブラウザダイアログ経由のファイルアップロード・ダウンロードは動作するが、使用するアプリで十分にテストする必要がある。すべてのSwingコンポーネントが完璧に動作するわけではなく、特にカスタムレンダラーやネイティブOSダイアログ系は注意が必要だ。

Community Editionの制限

無料だが実用上いくつかの制約がある:同時セッション数の上限、SSO/LDAP連携なし、セッション録画・クラスターモードなし。試用や小規模な社内利用であれば問題ないが、大規模なスケールや監査ログが必要な場合は商用版が必須となる。

2008年製のSwingアプリで実際に試してみた――コードは一行も変えず、JDKのバージョンさえ合わせればブラウザ上で動いた。LAN環境でのレイテンシはほぼ感じられず、インターネット経由でRTT約20msあっても通常の業務作業には十分快適に使えた。

まとめ

ネイティブWebアプリとして書き直せる選択肢があるならそうするべきだ――長期的には確実にすっきりする。だが、書き直しに6か月と予算が常に確保できるわけではない。その二択の間で身動きが取れなくなったとき、Webswingは私が試した中で最も苦痛の少ない脱出口だった。

ゼロから動くURLまで2時間以内。Javaコードには一行も触れていない。アプリをゼロから書き直す場合やCitrixライセンスを購入する場合と比べると、「Web化」を待ち続けているレガシーJavaアプリに対して、真剣に検討する価値のある数字だ。

Share: