Java 

拡張機能機構のアーキテクチャ

目次

はじめに

注: オプションパッケージは、これまで「標準拡張機能」として知られてきたものの新しい名称です。拡張機能機構は、オプションパッケージの使用をサポートする、Java 2 SDK および Java 2 Runtime Environment の機能です。

このドキュメントでは、「オプションパッケージ」を扱うための Java プラットフォームの機構について説明します。オプションパッケージは、1 つまたは複数の JAR ファイルにまとめられたパッケージの集まりで、Java プラットフォームを拡張する API を実装します。オプションパッケージはプラットフォームを拡張して、仮想マシンが、クラスパスに存在しないクラスをプラットフォームのコア API のクラスとして検索し、ロードできるようにします。

オプションパッケージの実装は、Java プログラミング言語で記述されたコードですが、まれに、プラットフォーム固有のネイティブコードが含まれる場合もあります。さらに、プロパティ、地域対応のカタログ、イメージ、直列化されたデータ、およびその他のリソースなど、そのオプションパッケージに固有の各種リソースが含まれることもあります。

Internet Explorer や Netscape Navigator などのブラウザでは、オプションパッケージは Java Plug-in によってサポートされています。

オプションパッケージは、オープンで標準的な API を実装したものです (Sun が提供するオプションパッケージは、JavaServletJava3DJavaManagement など)。例外もありますが、オプションパッケージの多くは javax.* の名前空間に割り当てられます。

拡張機能機構

アーキテクチャ

拡張機能機構は、次の要素を含むように設計されています。 したがって通常、アプリケーションでは、必要なオプションパッケージ (より一般的な言い方をすれば、ライブラリ) を指定して、さらに提供する必要があります。システムは、インストールされているオプションパッケージ (およびライブラリ) がある場合は、それを選び、ない場合は、参照されているオプションパッケージ (およびライブラリ) クラスの検索とロードをアプリケーションのクラスローダに委譲します。

このアーキテクチャでは、アプリケーション、アプレット、およびサーブレットがそれら自体のクラスパスを拡張できるので、それらを複数の JAR ファイルとしてまとめ、配置することも可能になります。

それぞれのオプションパッケージまたはアプリケーションは、少なくとも 1 つの JAR ファイルで構成されます。JAR ファイルにはマニフェスト、コード、各種リソースが含まれることもあります。後述するように、この主 JAR ファイルには、ほかの JAR ファイルとの依存関係を記述するため、そのマニフェストに付加情報を含めることもできます。オプションパッケージを JAR ファイルにまとめるためには ZIP 互換のアーカイブツールも利用できますが、Java 2 SDK に付属のコマンド行ツール jar を利用すると便利です。(jar ツールの参照ページ:[Win32][Solaris])

オプションパッケージまたはアプリケーションは、主 JAR ファイルから参照される別の JAR ファイルを参照することもあります。これらの JAR ファイルには、JAR ファイルごとに独自の依存関係情報を含めることもできます。

オプションパッケージを構成するパッケージは、オプションパッケージの実装時には、標準的なパッケージ命名規約に従って命名する必要があります。この命名規約は「Java 言語仕様」で大筋が示されていますが、ドメインの接頭辞はすべて大文字で指定するという規則はなくなりました。たとえば、COM.sun.server というパッケージ名は com.sun.server とも指定できます。アプリケーションとオプションパッケージは同じクラスローダを共有する場合があるので、名前の衝突を避けるため、パッケージには一意の名前を付けることをお勧めします。

オプションパッケージの配置

オプションパッケージは、アプリケーションにバンドルする (バンドル型) 方法と、すべてのアプリケーションで使用できるように JRE にインストールする (インストール型) 方法があります。バンドル型オプションパッケージはアプリケーションと同じコードベースに置かれ、ネットワークアプリケーション (アプレット) の場合は自動的にダウンロードされます。したがって、バンドル型オプションパッケージは、「ダウンロード型」オプションパッケージと呼ばれる場合があります。インストール型オプションパッケージは、最初に使用されるときにロードされ、その実行環境で動作するすべてのアプリケーションによって共有されます。

オプションパッケージをまとめる場合には、JAR ファイルのマニフェストはベンダーおよびバージョン情報を識別するために使用されます (「パッケージのバージョン管理の仕様」を参照)。

インストール型オプションパッケージのクラスは、同じ仮想マシン上のすべてのコードによって「共有」されます。したがって、インストール型オプションパッケージはそのプラットフォームの (rt.jar の) コアクラスに似ていますが、インストール型オプションパッケージは、後述するように、専用のクラスローダと事前に構成されたセキュリティポリシーを持ちます。

バンドル型オプションパッケージのクラスは、当該アプリケーション、アプレット、またはサーブレットのクラスローダだけが使用します。アプレットなどのネットワークアプリケーションの場合、バンドル型オプションパッケージは必要に応じて自動的にダウンロードされます。現時点では、クラスローダは特定のコードベースに関連付けられているので、同じコードベースに置かれたアプレットであれば実装 (JAR) を共有できます。

バンドル型オプションパッケージ

アプリケーションまたはオプションパッケージのマニフェストでは、必要なオプションパッケージ (およびその他のライブラリ) が含まれる JAR ファイルとディレクトリを参照する相対 URL を 1 つ以上指定できます。これらの相対 URL は、アプリケーションまたはオプションパッケージが含まれている JAR ファイルのロード元であるコードベースと相対的な位置関係にあるものとして扱われます。

アプリケーション (より一般的には、JAR ファイル) は、必要なオプションパッケージ (およびライブラリ) の URL を、マニフェスト属性 Class-Path で指定します。この属性では、ホストの Java 仮想マシン* にインストールされたオプションパッケージの中から目的のオプションパッケージ (またはその他のライブラリ) の実装が見つからなかった場合に検索する URL を列挙します。この相対 URL には、アプリケーションまたはオプションパッケージが必要とするライブラリまたはリソースが含まれる JAR ファイルとディレクトリを含めることができます。「/」で終わらない URL は、JAR ファイルを参照しているものとみなされます。次に例を示します。

Class-Path: servlet.jar infobus.jar acme/beans.jar images/
Class-Path ヘッダを複数指定することもできます。複数指定した場合は、順に連結されます。

現時点では、セキュリティ上の理由により、URL は JAR ファイルのコードベースから「相対的」に指定する必要があります。したがって、リモートオプションパッケージは、アプリケーションと同じコードベースを元にして指定します。将来的には、ほかの URL にある JAR ファイルを参照できるように、Java 2 プラットフォームの Security API の機能が利用できるようになる予定です。

それぞれの相対 URL は、アプリケーションまたはオプションパッケージが含まれている JAR ファイルのロード元であるコードベースと突き合わせる形で解決されます。解決された URL が無効であるか、参照するリソースが見つからない場合、その URL は無視されます。

解決された URL は、アプリケーション、アプレット、またはサーブレットのクラスパスの拡張に使用され、クラスパスの、そのアプリケーション、アプレット、またはサーブレットが含まれる JAR ファイルの URL の直後に挿入されます。重複する URL は 取り除かれます。たとえば、次のようなクラスパスが指定されているとします。

        a.jar b.jar
オプションパッケージ b.jar に、次のようなマニフェスト属性 Class-Path が含まれている場合、
        Class-Path: x.jar a.jar
最終的なアプリケーションクラスパスは次のようになります。
        a.jar b.jar x.jar
x.jar に依存情報が含まれる場合は、依存ファイルはこれと同じ規則に従って追加されます。あとに続く URL についても同様です。実際の実装では、JAR ファイルの依存関係は先に処理されるのではなく、JAR ファイルは実際に必要になったときまで開かれません。

インストール型オプションパッケージ

Sun による Java 2 プラットフォームの実装では、インストール型オプションパッケージの JAR ファイルは、次の標準のローカルコードソースに置かれます。
<java-home>¥lib¥ext                     [Win32]
<java-home>/lib/ext                     [Solaris]
そのネイティブコードライブラリは、存在する場合は、次の場所に置かれます。
<java-home>¥bin                         [Win32]
<java-home>/lib/<arch>                  [Solaris]
<java-home> は、ランタイムソフトウェアがインストールされているディレクトリ (JRE のトップレベルディレクトリまたは Java 2 SDK の jre ディレクトリ) を参照します。<arch> は、Solaris プロセッサアーキテクチャ (sparc または i386) を参照します。

インストール型オプションパッケージは、さらに 1 つ以上の共有ライブラリ (.dll ファイルなど) と実行可能ファイルを含んでいます。ネイティブライブラリは、Win32 と Solaris の両方の jre/lib/ext/<arch> ディレクトリに置かれます。Win32 システムでは、<arch>x86 です。jre/lib/ext/<arch> ディレクトリは、jre¥bin (win32) または jre/lib/<arch> (Solaris) の次に検索されます。

現時点では、ネイティブコードが含まれるオプションパッケージは、信頼できるコードか信頼できないコードかにかかわらず、実行時にネットワークコードにより仮想マシンにダウンロードすることはできません。ネイティブコードが含まれ、ネットワークアプリケーションとともにバンドルされているオプションパッケージは、Java 2 SDK または Java 2 Runtime Environment にインストールする必要があります。

デフォルトでは、この標準のディレクトリに置かれたインストール型オプションパッケージは信頼できます。つまり、このディレクトリに置かれたインストール型拡張機能には、コアプラットフォームクラス (rt.jar 内のクラス) の場合と同じ権限が与えられます。このデフォルトの権限はシステムポリシーファイルで指定されますが、適切なポリシーファイルエントリを追加することで、特定のオプションパッケージの権限をオーバーライドできます。

なお、信頼できるエンティティによりインストール型オプションパッケージの JAR ファイルに署名が付けられている場合、そのオプションパッケージには、署名を付けたエンティティに関連付けられている権限が与えられます。

システムプロパティ java.ext.dirs を使用すると、インストール型オプションパッケージを置く場所をほかにも指定できます。このプロパティには、インストール型オプションパッケージを検索するディレクトリを指定できます。複数のディレクトリを指定する場合は、File.pathSeparatorChar で区切ります。このプロパティのデフォルトの設定値は、上に示したインストール型オプションパッケージの標準のディレクトリになっています。

オプションパッケージのシーリング

JAR ファイルとパッケージは、同一バージョン内で整合性が保たれるように「シール」することができます。

JAR ファイル内のパッケージをシールした場合、そのパッケージ内で定義されているすべてのクラスは、同一の JAR ファイルが元になっていなければなりません。そうでない場合は、SecurityException がスローされます。

JAR ファイルをシールした場合、その JAR ファイルで定義されているすべてのパッケージは、特別に設定をオーバーライドしない限り、シールされます。

パッケージをシールするかどうかは、マニフェスト属性 Sealed で指定します。 このマニフェスト属性は、truefalse の値をとります。 大文字小文字は区別されません。次に例を示します。

        Name:javax/servlet/internal/
Sealed:true
このように指定すると、javax.servlet.internal がシールされ、このパッケージに含まれるすべてのクラスは同一の JAR ファイルからロードされなければなりません。

この属性が指定されていない場合は、パッケージのシール属性は、そのパッケージが含まれる JAR ファイルのシール属性と同じになります。

JAR ファイルをシールするかどうかは、上と同じマニフェストヘッダ Sealed で指定します。このマニフェストヘッダも、同じく truefalse の値をとります。次に例を示します。

Sealed: true
このように指定すると、このアーカイブに含まれるすべてのパッケージは、マニフェストエントリの中で Sealed 属性により明示的に設定をオーバーライドしない限り、シールされます。

この属性が指定されていない場合は、下位互換性を保つため、そのモジュールはシールされていないものとみなされます。このあと、システムはシール情報を見るため、パッケージのヘッダのチェックを継続します。

パッケージをシールすると、パッケージ保護されたメンバへのアクセスは、同一の JAR ファイルが元になるパッケージで定義されているクラスに制限されるため、パッケージのシールはセキュリティの上でも重要です。

パッケージシーリングのチェックは、ダウンロード型オプションパッケージだけでなくインストール型オプションパッケージについても行われ、違反があった場合は SecurityException がスローされます。また、null パッケージはシールできないので、シールすべきクラスはその独自のパッケージ内に置く必要があります。

オプションパッケージのセキュリティ

インストール型オプションパッケージのコードソース (<java-home>/lib/ext) には、事前に構成されたセキュリティポリシーが割り当てられています。Sun の実装では、このディレクトリに置かれた JAR ファイルに与えられる正確な信頼度レベルは、次の標準のセキュリティポリシー構成ファイルによって指定されます。
<java-home>/lib/security/java.policy
デフォルトのポリシーは、インストール型オプションパッケージが、コアプラットフォームの一部である場合と同じように動作できるようにするためのものです。これは、インストール型オプションパッケージがネイティブコードをロードするという一般的な必要性に基づいています。

Java Security Model は、インストール型オプションパッケージのコードが信頼できないコードから呼び出された場合のために、ある種の安全策を提供しています。しかし、オプションパッケージのコードが特権ブロックを使用する場合は必ず、セキュリティ上の危険性がないかどうかコードを十分に確認する必要があります。

リモートからロードされるオプションパッケージで、正常な動作のため、アクセスチェックが行われるシステムサービス (ファイル入出力など) を使用する必要があるものについては、信頼できるエンティティによる署名が付けられたものであるか、信頼できる場所からロードされたものでなければなりません。

Java 2 プラットフォームのセキュリティ機能を利用するためのオプションパッケージやアプリケーションのコードを記述する方法の詳細については、Java 「セキュリティ」を参照してください。

API の詳細

拡張機能機構は、Java 2 プラットフォームの次のクラスでサポートされています。

* この Web サイトで使用されている用語「Java 仮想マシン」または「JVM」は、Java プラットフォーム用の仮想マシンを表します。


Copyright © 1997-1999 Sun Microsystems, Inc.All Rights Reserved.

コメントの送付先:Java ソフトウェア

Sun