このセクションでは、次のトピックについて説明します。
JnlpDownloadServletの使用JnlpDownloadServletの構築JnlpDownloadServletは、Java Web StartアプリケーションをWebサーバーに配備するとともに拡張機能を提供するプロセスを簡素化するサーブレットです。 JnlpDownloadServletは、コンパイル済みJARファイルおよびソース・コードの両形式で、JDKのsample/jnlp/servletディレクトリに用意されています。
もっとも単純なJNLP配備の場合、アプリケーション・ファイルとJNLPファイルをWebサーバー上に置きます。 JNLP MIMEタイプ用にWebサーバーを構成すると、基本的なJNLP機能が使用可能になります。つまり、ユーザーがブラウザでJNLPファイルのリンクをクリックすると、アプリケーションがダウンロードされて実行されます。
ただし、この方法にはいくつかの欠点があります。 まず、アプリケーションのコード・ベースのURLをJNLPファイルに明示的に指定する必要があります。 したがって、アプリケーションを別の場所でホストすることにした場合や、ローカルのテスト・サーバーから公開の本稼働サーバーに移行する場合に、その変更が必要になります。 次に、アプリケーションのタイムスタンプを報告するためにアプリケーション・ファイル上のファイル・システム・タイムスタンプが使用されますが、これは望ましくない場合があります。 最後に、HTTPを介して実装されるのはJNLPプロトコルのもっとも基本的な部分だけです。 バージョン管理などのほかの機能はサポートされません。
JnlpDownloadServletは、アプリケーション・ファイルとクライアントとのパイプ役として機能します。 これによって次の機能が提供されます。
JnlpDownloadServletによって提供されるアプリケーション配備の便利な機能について理解するには、JNLPとJava Web Startを使用してアプリケーションを配布するもっとも単純な方法をまず理解する必要があります。
app1例(JDKのsample/jnlp/servletディレクトリ内)には、単純なアプリケーションと、有用性の高いAntビルド・スクリプトが含まれています。Antビルド・スクリプトは、アプリケーションを構築してWebサーバーでの配布用のWARファイルにバンドルします。
アプリケーション自体は単一のクラスPieとイメージ・ファイルkey-lime.jpgから成り、これらはpie.jar JARファイルにパッケージ化されています。
pie.jarアーカイブはWebアプリケーション・ファイルapp1.warにパッケージ化されています。その内容は次のとおりです。
WEB-INF/web.xml index.html pie.jnlp pie.jar
JNLPファイルは、アプリケーションがhttp://localhost:8080/のサーバーに配備されると想定してアプリケーションを記述しており、ローカルにインストールされたTomcatサーバーで機能します。
<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0+" codebase="http://localhost:8080/app1">
<information>
<title>Pie</title>
<vendor>Example Vendor</vendor>
</information>
<resources>
<j2se version="1.2+"/>
<jar href="pie.jar" main="true" />
</resources>
<application-desc/>
</jnlp>
クライアントとサーバーのやりとりは次のような対話と見なすことができます。
[ユーザーがブラウザでリンクをクリックします。]
クライアント・ブラウザ: pie.jnlpをください。
サーバー: はい、どうぞ。
クライアント・ブラウザ: MIMEタイプはapplication/x-java-jnlp-fileなのですね。 Java Web Startさん、私のためにpie.jnlpを処理してください。
クライアントJava Web Start: このアプリケーションにはどのようなリソースが必要なのか調べてみます。 サーバーさん、pie.jarをください。
サーバー: はい、どうぞ。
クライアントJava Web Start: それでは、JARファイルのMain-classマニフェスト属性を使ってこのファイルを起動します。
[ユーザーの画面にアプリケーションが表示されます。]
app2の例では、JnlpDownloadServletをアプリケーションとバンドルする方法と、それを使用してJNLPファイルで単純な置換を実行する方法が示されています。
app3の例は、バージョン管理されたリソース要求がJnlpDownloadServletでどのように処理されるかを示しています。
app2とapp3はどちらも、以降のセクションで参照されています。
JnlpDownloadServletの使用JnlpDownloadServletを利用するには、次のステップを実行します。
JnlpDownloadServletをWebアプリケーションのWARファイルにパッケージ化します。 すべての機能を利用するには、2つのJARファイルjnlp-servlet.jarおよびjardiff.jarを使用する必要があります。 これら2つのJARファイルをWARファイルのWEB-INF/libディレクトリに置きます。 *.jnlpおよび*.jarの要求をJnlpDownloadServletにマッピングします。 このファイルには、JnlpDownloadServletを識別してJNLPファイルとJARファイルのハンドラにする行が含まれている必要があります。 完全な例を次に示します。
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<servlet>
<servlet-name>JnlpDownloadServlet</servlet-name>
<servlet-class>jnlp.sample.servlet.JnlpDownloadServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>JnlpDownloadServlet</servlet-name>
<url-pattern>*.jnlp</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>JnlpDownloadServlet</servlet-name>
<url-pattern>*.jar</url-pattern>
</servlet-mapping>
</web-app>
app2の例とapp3の例では、JnlpDownloadServletをWebアプリケーションにパッケージ化する方法が示されています。 詳細は、Antビルド・スクリプトapp2/build.xmlまたはapp3/build.xmlを参照してください。
JnlpDownloadServletはJNLPファイルで簡易置換を行います。 クライアントがJNLPファイルを要求すると、このサーブレットが元のファイルを読み取り、値を置換し、結果を返します。
JNLPファイルの最初の行にタイムスタンプが含まれている場合、JnlpDownloadServletはその値をアプリケーションのタイムスタンプとして使用します。 タイムスタンプが指定されていない場合、JnlpDownloadServletはファイル・システムの最終変更時間のタイムスタンプを使用します。
明示的なタイムスタンプを使用することは、負荷分散のためにJNLPファイルを複数のサーバーにコピーする場合に役立ちます。 明示的なタイムスタンプにより、クライアントはどのサーバーを参照しても一貫した結果を得ることができます。
明示的なタイムスタンプを使用するには、JNLPファイルの先頭に1行を追加します。 この行はTS:で始まります。 この行の残り部分には、ISO 8601形式のタイムスタンプを含める必要があります。その基本的な形式は次のとおりです。
YYYY-MM-DD hh:mm:ss
次に例を示します。
TS: 2010-08-07 21:19:05
タイムスタンプ文字列の詳細な説明については、「参照情報」セクションを参照してください。
JnlpDownloadServletは、2つのドル記号で始まる文字列を置換します。 たとえば、JNLPファイルに次の行があるとします。
<jnlp spec="1.0+" codebase="$$codebase">
クライアントがJNLPファイルを要求すると、配備されるたびにJnlpDownloadServletが$$codebaseを正しい値で置換します。 この値をJNLPファイルにハードコードする必要がなく、別のサーバーへの移行がより簡単になるため、これは便利です。
すべての置換のリストを次の表に示します。
| 名前 | 置換される値 |
|---|---|
$$codebase |
JNLPファイルの名前を除く、要求のURL |
$$name |
JNLPファイルの名前 |
$$context |
WebアプリケーションのベースURL |
$$site |
Webサーバーのアドレス |
$$hostname |
サーバーの名前 |
たとえば、app2の例がexample.comに配備されるとします。 各置換の値は次のようになります。
| 名前 | 置換される値 |
|---|---|
$$codebase |
http://example.com/app2/ |
$$name |
pie.jnlp |
$$context |
http://example.com/app2 |
$$site |
http://example.com |
$$hostname |
example.com |
app2/pie.jnlpの例とapp3/pie.jnlpの例は$$codebaseのみを使用します。
JNLP仕様では、明示的なバージョン番号を指定してアプリケーション・リソースを要求することや、特定のロケール、オペレーティング・システム、システム・アーキテクチャのリソースを要求できます。 つまり、オペレーティング・システムによってライブラリの異なるアプリケーションや、ロケールによってリソース・ファイルの異なるアプリケーションを配備できます。
JnlpDownloadServletは、特殊な要求を2つの異なるメカニズムでサポートします。 1つ目は、ロケールやオペレーティング・システムなどのパラメータをファイル名に埋め込む、リソース・ファイルの命名スキームです。 2つ目のメカニズムは、同じディレクトリ内のリソース・ファイルのパラメータを記述するXMLファイルを利用します。
JnlpDownloadServletでは、ファイルに関する情報をファイル名に埋め込むことによって指定できます。 ファイル名に2つ並んだアンダースコアが含まれている場合、ファイル名は属性を含んでいると見なされます。 接頭辞文字は、次のように属性の情報を指定します。
| 接頭辞 | 意味 |
|---|---|
V |
バージョン番号 |
O |
オペレーティング・システム |
A |
アーキテクチャ |
L |
ロケール |
1つのファイルにバージョンは1つだけ指定できますが、オペレーティング・システム、アーキテクチャ、またはロケール属性は複数関連付けることができます。 たとえば、application__V1.2__Len_US__Len.jarは、リソースapplication.jarのバージョンが1.2で、関連付けられたロケールがen_USとenであることを意味します。
たとえば、JNLPファイルに次のリソース行があるとします。
<jar href="app-lib.jar" version="2.0" />
Java Web Startは、JNLPファイルにこの行を見つけると、app-lib.jarのバージョン2.0の要求をサーバーに送信します。 Webアプリケーション内にファイルapp-lib__V2.0.jarが置かれている場合、JnlpDownloadServletはそれをapp-lib.jarのバージョン2.0としてクライアントに返します。 Webアプリケーション内の実際のファイル名が再マッピングされ、app-lib.jarとしてクライアントに表示されることに注意してください。
ファイル命名規則は煩雑になることがあり、複数のリソース・ファイルが存在し、それぞれにオペレーティング・システム、アーキテクチャ、またはロケールが複数関連付けられている場合は特にそうなります。
JnlpDownloadServletは代替のメカニズムをサポートしており、そこではすべての属性が別のXMLファイルに記述されます。 このサーブレットは、リソースと同じディレクトリでversion.xmlファイルを探します。 version.xmlファイルには、同じディレクトリ内のほかのファイルに関する情報が含まれています。
たとえば、次のversion.xmlファイルでは、クライアントにはapplication.jarとして使用可能になるリソースが記述されています。 実際のファイルは、同じディレクトリにapplication-1_2-us.jarとして格納されています。
<jnlp-versions>
<resource>
<pattern>
<name>application.jar</name>
<version-id>1.2</version-id>
<locale>en_US</locale>
<locale>en</locale>
</pattern>
<file>application-1_2-us.jar</file>
</resource>
</jnlp-versions>
app3の例では、バージョン管理されたリソース要求にXMLバージョン・ファイルを使用して応答する方法が示されています。 特に、JNLPファイルには次のリソース行があります。
<jar href="app-lib.jar" version="2.0" />
WARファイルには、ライブラリ、app-lib.jar、およびライブラリを記述する次のXMLバージョン・ファイルversion.xmlが含まれています。
<jnlp-versions>
<resource>
<pattern>
<name>app-lib.jar</name>
<version-id>2.0</version-id>
</pattern>
<file>app-lib-2.0.jar</file>
</resource>
</jnlp-versions>
実際のファイル名app-lib-2.0.jarが再マッピングされ、クライアントに表示されるファイル名はapp-lib.jarとなることに注意してください。
JnlpDownloadServletは、可能であればJARファイルの増分更新を生成して返します。 要求にcurrent-version-idパラメータが含まれている場合、このサーブレットがcurrent-version-idおよび要求されたバージョンの両方に一致するものを見つけることができ、かつ要求がJARファイルに対するものであれば、サーブレットによってJARDiffファイルが生成されます。 JARDiffファイルは、そのサイズが要求されたバージョンのサイズよりも小さい場合に返されます。
生成されたJARDiffファイルは、Webコンテナに固有の一時ディレクトリに格納されます。 サーブレットは、javax.servlet.context.tempdirコンテキスト属性を使用して一時作業ディレクトリを見つけます。
Pack200は、JARファイルの効率的な圧縮テクノロジです。 アプリケーションのダウンロード時間とインストール時間は、ユーザーがアプリケーションをどのように感じるかを決定する重要な要因です。 アプリケーション・リソースをできるだけ小さくすると、ユーザーがアプリケーションのダウンロードを待たなければならない時間が短縮されます。
JnlpDownloadServletは、GZIPおよびPack200ダウンロードをサポートしているクライアント(Java Web Startなど)にリソースを提供できます。 *.jar.pack.gzファイルまたは*.jar.gzファイルを元の*.jarファイルとともにサーバー上に配置してください。 たとえば、JnlpDownloadServletは、クライアントがサポートしているものに基づいて、次の中から最適なファイルを選択します。
pie.jar pie.jar.gz pie.jar.pack.gz
Pack200ファイルは、Java Development Kitに含まれているpack200ツールを使用して作成できます。 app3の例では、pie.jarファイルのPack200版が作成されます。 Pack200ファイルがどのように作成されるかを確認するには、build.xmlを調べてください。 pie.jarはシンプルなのでPack200ファイルはごくわずかしか小さくなりませんが、より大きいJARファイルであれば、圧縮率ははるかに大きくなります。
JNLPの置換、Pack200のサポート、およびファイル属性のサポートは、JnlpDownloadServletのもっとも有用な機能です。 このサーブレットは、ロギング・システムおよびMIMEタイプ・マッピングもサポートしています。
このサーブレットは、その動作をモニターするためのログ機能を備えています。 生成されるログ・メッセージは、次のカテゴリに分けられます。
FATALは、サーブレット内部で発生した機能不全エラーまたは内部エラーを示します。WARNINGは、WARファイル内の情報の処理中またはversion.xmlファイルの構文解析中に発生したエラーを示します。INFORMATIONALは、すべての要求、応答、ディレクトリ走査などのログです。DEBUGは、要求がどのように処理されているかを示す詳細な内部情報を表示します。ログ出力は、2つのサーブレット初期化パラメータlogPathとlogLevelによって制御されます。 ログ・レベルは、NONE、FATAL、WARNING、INFORMATIONAL、DEBUGのいずれかに設定できます。 ログ・パスには、出力の書込み先のファイルを指定します。 パスを指定しない場合、ログはサーブレットの標準ログに書き込まれます(ServletContext.log()を使用)。 次はその例です。
<servlet>
<servlet-name>
JnlpDownloadServlet
</servlet-name>
<servlet-class>
jnlp.sample.servlet.JnlpDownloadServlet
</servlet-class>
<init-param>
<param-name>
logLevel
</param-name>
<param-value>
DEBUG
</param-value>
</init-param>
<init-param>
<param-name>
logPath
</param-name>
<param-value>
/logs/jnlpdownloadservlet.log
</param-value>
</init-param>
</servlet>
サーブレットは、JNLPファイルとJARファイルを特別に扱います。 置換で説明されているように、JNLPファイルで置換が行われます。 JARファイルに対するバージョン・ベースの要求によって、増分更新が生成されることがあります。 サーブレットは、拡張子を利用して、ファイルがJNLPまたはJARのどちらであるかを特定します。 JNLPファイルのデフォルトの拡張子は.jnlp、JARファイルのデフォルトの拡張子は.jarです。 これらのデフォルトの拡張子は、初期化パラメータjnlp-extensionとjar-extensionを使って変更できます。 次はその例です。
<init-param>
<param-name>
jnlp-extension
</param-name>
<param-value>
.xjnlp
</param-value>
</init-param>
返されるMIMEタイプも、ファイルの拡張子に基づいて決定されます。 MIMEタイプは、WebコンテナやWARファイルの構成ファイルで確認されます。 マッピングが指定されていない場合は、デフォルトのMIMEタイプが割り当てられます。
| 拡張子 | デフォルトのMIMEタイプ |
|---|---|
.jnlp |
application/x-java-jnlp-file |
.jar |
application/x-java-archive |
.jardiff |
application/x-java-archive-diff |
JnlpDownloadServletから返されるMIMEタイプを変更するには、web.xmlファイルの<mime-type>要素を使用します。 次はその例です。
<web-app>
...
<mime-mapping>
<extension>jnlp</extension>
<mime-type>text/ascii</mime-type>
</mime-mapping>
...
</web-app>
JnlpDownloadServletの構築ほとんどの場合はJnlpDownloadServletをそのまま使用します。 まれに、JnlpDownloadServletに機能を追加したい場合があります。 完全なソース・コードが提供されており、構築は比較的簡単です。
GNU makeとJava Development Kit (JDK)が必要で、環境変数を定義する必要があります。 次はLinuxシステムでの例です。
$ export CLASS_PATH=/home/edmond/Applications/apache-tomcat-7.0.2/lib/servlet-api.jar $ export FILE_SEPARATOR=: $ export TMPDIR=/tmp $ export SDK_HOME=/home/edmond/jdk1.7.0 $ make . . .
構築によって出力されるのはlib/jnlp-servlet.jarとlib/jardiff.jarです。
一般的なタイムスタンプの形式は、次のとおりです。
YYYY-MM-DD hh:mm:ss
次に示すように、ダッシュ、コロン、および秒を付けずに記述することもできます。
YYYYMMDDhhmm
hhは24時間単位で表記します。 デフォルトでは、ローカル・タイムゾーンが使用されます。 時間の最後に大文字のZを追加することにより、UTC (世界標準時、GMTとしても知られる)を指定することもできます。
23:59:59Z or 235959Z
文字列+hh:mm、+hhmm、または+hhを時間に追加することにより、ローカル・タイムゾーンがUTCよりhh時間mm分進んでいることを指定できます。 経度ゼロより西のタイムゾーン(UTCより遅れている)の場合は、代わりに-hh:mm、-hhmm、または-hhという表記を使用します。 たとえば、中央ヨーロッパ標準時(CET)は+0100、米国およびカナダの東部標準時(EST)は -0500となります。 次の文字列は、すべて同じ時間を指します。
12:00Z = 13:00+01:00 = 0700-0500
version.xmlファイルの完全な文書型定義(DTD)は次のとおりです。
<!ELEMENT jnlp-versions <resource*, platform*)> <!ELEMENT resource (pattern, file)> <!ELEMENT platform (pattern, file, product-version-id)> <!ELEMENT pattern (name, version-id, os*, arch*, locale*)> <!ELEMENT name (#PCDATA)> <!ELEMENT version-id (#PCDATA)> <!ELEMENT os (#PCDATA)> <!ELEMENT arch (#PCDATA)> <!ELEMENT locale (#PCDATA)> <!ELEMENT file (#PCDATA)> <!ELEMENT product-version-id (#PCDATA)>