jnlpとコードベース

先日紹介した「任意のJava Web Start(以降 JWS)アプリケーションが起動されているかを調べる」だが、上手くいかないケースがあることが判明した。
エントリで書いたように、アプリケーション中から

javaws.exe JNLPをダウンロードするURL

と起動したケースでは問題が無いのだが、例えばHTMLのアンカーから起動した(Webブラウザから起動した)場合、VirtualMachineDescriptor.displayName()つまりプロセスの表示名に、起動したJNLPのURLは渡されないのである。

であれば何が渡されるのか?

実際にProcess Explorerで調べてみたが、私の環境(Windows Vista SP1)だと、以下のパスでJava仮想マシンが起動されていることが判る

"C:\Program Files\Java\jre1.6.0_06\bin\javaw.exe" "-Xbootclasspath/a:C:\Program Files\Java\jre1.6.0_06\lib\javaws.jar;C:\Program Files\Java\jre1.6.0_06\lib\deploy.jar" -classpath "C:\Program Files\Java\jre1.6.0_06\lib\deploy.jar" "-Djava.security.policy=file:C:\Program Files\Java\jre1.6.0_06\lib\security\javaws.policy" -DtrustProxy=true -Xverify:remote "-Djnlpx.home=C:\Program Files\Java\jre1.6.0_06\bin" -Djnlpx.remove=true -Djnlpx.splashport=50624 "-Djnlpx.jvm=\"C:\Program Files\Java\jre1.6.0_06\bin\javaw.exe\"" com.sun.javaws.Main C:\Users\KAZZ~1\AppData\Local\Temp\javaws3

前半のパラメタは良いとして、問題は最後だ。結局はjavawsのMainクラスをパラメタ付きで起動しているのだが、そこに渡されているパスはURLではなくユーザローカルの一時ファイル置き場である。

ここからは推測だがシェルやWebブラウザ等、OS経由でJavaws.exeが起動された場合、

1. jnlpが配置されているリソース(URL又はローカルパス)を確認する
2. 対象のjnlpファイルをJava Web Startの一時領域(上の例"C:\Users\KAZZ~1\AppData\Local\Temp\")にコピーする
3. javaws.jarのエントリポイントをコピーしたjnlpを使って起動

という手順を踏んでいるのだろう。

さて、一般的な起動方法で起動したJWSアプリケーションにはjnlpへの正しいパスが渡されていないことが判ったが、ならばどうすればよいだろう。
幸運にも? jnlpファイルはどこにコピーされても正しい位置から起動するため、そのルート要素にアプリケーションのコードベースを記述する属性があり、通常はここに起動時のURLを記述する。

<jnlp spec="1.0+" codebase="http://hogehost:8800/app/jws" href="hogeapp.jnlp">
〜
</jnlp>

あとはこの記述された内容をアプリケーションから取得すれば良いのだが、それにはJNLP API、javax.jnlpBasicServiceパッケージで提供されているAPIが使える。

BasicService basicService = (BasicService) ServiceManager.lookup("javax.jnlp.BasicService");
URL codeBaseURL = basicService.getCodeBase();

BasicServiceインタフェースはJWSアプリケーションのコンテキスト中であれば、取得できるはずだ。
これで起動されたアプリケーションのURL(コードベース)を取得することができたが、あくまで自らが起動された場合のことであって、他のアプリケーションことまで調べることはできない。となると、

  • RMIなどで起動されたURLを公開、共有する
  • 起動されたコードベースを取得するエージェントを用意し、アタッチAPI経由で注入してURLを取得する

など、他のアプリケーションの情報を調べるための方法が必要になってくる。

う〜ん、思いの外面倒になってきたな...