ブラウザから1クリックでアプリケーションを起動する - Java Web Start 〜 JavaFX

festivoice.netはブラウザから1クリックで専用のクライアントソフトウェアが起動して、簡単に音声チャットが始められます。この1クリックでアプリケーションを起動する仕組み - Java Web StartJavaに標準で搭載されているので、大抵の環境でインストールする手間を掛けることなくクライアントを配布できます。
またサーバーに置いてあるパッケージを更新するとクライアントも自動的にアップデートされます。Webサービスの提供者側からすると、Java Web Startはかなり便利です。


Java Web Startを利用するには、サーバー上に 1)普通のJavaのアプリケーション と、2) JNLPファイル を用意します。JNLPファイルはXMLの設定ファイルで、以下のようなフォーマットになります:

<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.5+" codebase="http://festivoice.net/start/" href="../pkg/festivoice.net.jnlp">
	<!-- ↑JNLPのバージョン、この先で指定する各種パスの起点となるURL、JNLP自体のURLを指定 -->

	<information>
		<title>festivoice.net</title>
		<vendor>festivoice developer team</vendor>
	</information>

	<resources>
		<!-- ↓ アプリケーションの実行に必要なJavaのバージョンを指定(ここではJRE 1.5以上) -->
		<j2se version="1.5+"/>
		<!-- ↓ アプリケーション本体(jarファイル)のパスを指定 -->
		<jar href="../pkg/festivoice.jar"/>
	</resources>

	<!-- ↓ main()が入っているクラス名と、main()に渡す引数を指定 -->
	<application-desc main-class="festivoice.net">
		<argument>-G</argument>
		<argument>stream.festivoice.net</argument>
		<argument>11100</argument>
		<argument>-</argument>
		<argument>-</argument>
	</application-desc>

	<!-- ↓ アプリケーションの更新を常にチェック -->
	<update check="always" policy="always" />
</jnlp>


Javaがインストールされていれば、JNLPファイル(application/x-java-jnlp-file)はデフォルトでJava*1に関連付けられています。このため後はJNLPファイルへのリンクを張ってやるだけで、Java Web Startを使ってアプリケーションを起動させることができます。

festivoice.netではサーバー側でJNLPファイルを自動生成しており、チャンネル一覧からリンクを選んでクリックすると、自動的にそのチャンネル名が引数に指定されたJNLPファイルが生成されるようになっています。このため「接続」ボタンをクリックするだけですぐに音声チャットが始められるようになっています。


Java Web Startを使って起動したアプリケーションは「普通の」アプリケーションで、SwingやOpenGLでも使うことができます。(参考:リリースされたJava SE 6 Update 10で何が変わったのか?
JavaScriptでは実現不可能なこと(UDPで通信するなど)や遅すぎてやってられないこと(リアルタイムで音声圧縮するなど)もJavaを使って実現できます。
Flashと比べると、RTMPに縛られず自前でUDP通信ができたり、NetConnectionに縛られずに音声コーデックを自前で用意して使えたり、本当に並列するスレッドが使えたりと、制約が少ないのがポイントです。


ブラウザの中でJavaアプリケーションを起動する

先日モバイルにも対応したと噂のJava FX戦略の影響か、ブラウザからJavaアプリケーションを起動するための仕組みが随分と使いやすくなっています。表面的には古きJavaAppletを拡張したもののようですが、JDK 6 update 10の更新を見てみると、内部的には大幅に書き直されているようです。


前述のJava Web Start用のJavaアプリケーション(Swing)を、ほぼそのままの形でブラウザの中で起動するようにすることができます。
Java Web Startとの違いは、JavaAppletではエントリポイントがmain()ではなくJAppletクラスを継承したクラスのinit()メソッドになる点です(参考コード:net.festivoice.AppletLauncher.java


JavaAppletをHTMLに埋め込むには、Flashで言うところのswfobject.jsと同じように、deployJava.jsを使うことができます(参考:Java Web App Deployment Advice for JavaSE 6u10

<script src="http://java.com/js/deployJava.js"></script>
<script>
    // パスの起点、init()が実装されたクラス名、jarファイル、幅と高を指定
    var attributes = { codebase: 'http://festivoice.net/', code: 'net.festivoice.AppletLauncher', archive: 'pkg/festivoice.jar', width: 300, height: 200 };
    // 引数を指定
    var parameters = { host: 'stream.festivoice.net', port: 11100, user: '-', channel: '-' };
    deployJava.runApplet(attributes, parameters, '1.5');  // 1.5: このアプリケーションの実行に必要なJavaのバージョンを指定
</script>

このスクリプトを書いておくと、Javaがインストールされていないブラウザでアクセスしたときに自動的にインストールガイドが表示されます(実はもっと簡単にできる?:How to Deploy a JavaFX Applet


Java Web StartとJavaAppletではセキュリティーポリシーが若干異なるようです*2。セキュリティについて詳しくはこのあたり:Java Plug-in 6.0 開発者ガイド

DOM・CSSJavaScriptを操作する

ここからは試していないのですが、JavaAppletからDOMやCSSを操作したり、JavaScriptとデータをやりとりしたりできるようです。

HTMLのDOMツリーはJava 6 update 10から用意されたAPIを使って取得することができ、Javaの共通DOM API(org.w3c.dom)を使って操作できるようです。(サンプルコード:DOMDump.java

org.w3c.dom.Document document =
        com.sun.java.browser.plugin2.DOM.getDocument(this);

新しいCommon DOM APIのリファレンスを見る限りではCSSを操作するAPIも用意されており、状況が許せばクロスブラウザ問題に悩まされずにHTMLを自由に操作できそうです。

JavaScriptを扱う方法はこのあたりから各種ドキュメントをたどれます:netscape.javascript.JSObect


面白いのは、JavaScriptからJavaだけでなくJVM上で動く他の言語(JRubyJythonJavaFX Script…)のメソッドも呼び出せるらしい点です:JavaScript からの Java 以外の言語の呼び出し
サーバーサイドとクライアントサイドで同じ言語を使えるというのは、コードの一部を共有できたりして快適です*3Ruby on Rails + Java/JRuby という組み合わせで使うと便利なのかも知れません。

JavaFX

…と、どうも最近Sun Microsystemsが本気を出しているようで、JavaFXのページからたどると他にも色々と仕組みが用意されているようです*4
Drag-to-Installのデモはかなり面白いです。

Flash/FlexByteArrayをいじりつつ Socketのセキュリティーにハマりつつ 制約の多さが気にくわない 方は、Javaを試してみると良いかも知れません :-p

*1:javawsコマンド。2009/02/14時点でLinux x64版のSun JREにはjavawsコマンドが入っていない(Java Web Startが使えない)ので注意。JRE 6 update 12でサポートされた模様。

*2:理由は不明ですがMac OS Xではファイアウォールの挙動が変わったりします。Javaは必須サービスだけど、ブラウザはフィルタリング対象らしいです。

*3:[http://festivoice.net/:title=festivoice]はクライアント〜サーバー〜Webアプリまで一貫してJavaなので、インタフェースの擦り合わせや余分な通信が一切無くて快適。

*4:Flex」と同様に、「JavaFX」という単語自体が何を指しているのかは良く分からない…