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)>