このドキュメントでは、オプションパッケージを処理するための Java™ プラットフォームが提供するメカニズムについて説明します。オプションパッケージは、1 つまたは複数の JAR ファイルにまとめられたパッケージの集まりで、Java プラットフォームを拡張する API を実装します。オプションパッケージはプラットフォームを拡張して、仮想マシンが、クラスパスに存在しないクラスをプラットフォームのコア API のクラスとして検索し、ロードできるようにします。
オプションパッケージは、プラットフォームのコア API を拡張するため、適切に適用する必要があります。通常は Java Community ProcessSM で定義されたインタフェースなど、適切に標準化されたインタフェースのために使用されますが、サイト全体のインタフェースに適用されることもあります。オプションパッケージが単一または少数のアプリケーションで使用されるインタフェースに適用されることはほとんどありません。
また、インストール型オプションパッケージで定義される記号はどの JAVA プロセスでも視認できるため、必ずすべての参照可能な記号が所定の「逆順ドメイン名」および「クラス階層」の規約を守っているか気を付けて見るようにします (com.mycompany.MyClass など)。
オプションパッケージの実装は、Java プログラミング言語で記述されたコードですが、まれに、プラットフォーム固有のネイティブコードが含まれる場合もあります。さらに、プロパティー、ローカリゼーションのカタログ、イメージ、直列化されたデータ、およびその他のリソースなど、そのオプションパッケージに固有の各種リソースが含まれることもあります。
Internet Explorer や Netscape Navigator などのブラウザでは、オプションパッケージは Java Plug-in によってサポートされています。
オプションパッケージは、オープンで標準的な API を実装したものです (Sun が提供するオプションパッケージは、JavaServlet、Java3D、JavaManagement など)。例外もありますが、オプションパッケージの多くは javax.* の名前空間に割り当てられます。
このアーキテクチャーでは、アプリケーション、アプレット、およびサーブレットがそれら自体のクラスパスを拡張できるので、それらを複数の JAR ファイルとしてまとめ、配置することも可能になります。
それぞれのオプションパッケージまたはアプリケーションは、少なくとも 1 つの JAR ファイルで構成されます。JAR ファイルにはマニフェスト、コード、各種リソースが含まれることもあります。後述するように、このプライマリ JAR ファイルには、ほかの JAR ファイルとの依存関係を記述するため、そのマニフェストに付加情報を含めることもできます。JDKに収録されている jar コマンド行ツールには、オプションパッケージをひとまとめにする便利な機能があります。(jar ツールの参照ページ: [Microsoft Windows] [Solaris™ Operating System (Solaris OS)、Linux])
オプションパッケージまたはアプリケーションは、プライマリ JAR ファイルから参照される別の JAR ファイルを参照することもあります。これらの JAR ファイルには、JAR ファイルごとに独自の依存関係情報を含めることもできます。
オプションパッケージを構成するパッケージは、オプションパッケージの実装時には、標準的なパッケージ命名規約に従って命名する必要があります。この命名規約は「Java 言語仕様」で大筋が示されていますが、ドメインの接頭辞はすべて大文字で指定するという規則はなくなりました。たとえば、COM.sun.server というパッケージ名は com.sun.server とも指定できます。アプリケーションとオプションパッケージは同じクラスローダーを共有する場合があるので、名前の衝突を避けるため、パッケージには一意の名前を付けることをお勧めします。
オプションパッケージをまとめる場合には、JAR ファイルのマニフェストはベンダーおよびバージョン情報を識別するために使用されます (「パッケージのバージョンID」を参照)。
インストール型オプションパッケージのクラスは、同じ仮想マシン上のすべてのコードによって共有されます。したがって、インストール型オプションパッケージはそのプラットフォームの (rt.jar の) コアクラスに似ていますが、インストール型オプションパッケージは、後述するように、専用のクラスローダーと事前に構成されたセキュリティーポリシーを持ちます。
バンドル型オプションパッケージのクラスは、該当アプリケーション、アプレット、またはサーブレットのクラスローダーだけが使用します。アプレットなどのネットワークアプリケーションの場合、バンドル型オプションパッケージは必要に応じて自動的にダウンロードされます。現時点では、クラスローダーは特定のコードベースに関連付けられているので、同じコードベースに置かれたアプレットであれば実装 (JAR) を共有できます。ただし、前述のようにバージョン情報を持ち署名されたバンドル型オプションパッケージが JRE にインストールされている場合、それらの内容は、同じ JRE によって動作するすべてのアプリケーションで使用可能であり、専有されるものではありません。
アプリケーション (より一般的には、JAR ファイル) は、必要なオプションパッケージ (およびライブラリ) の URL を、マニフェスト属性 Class-Path で指定します。この属性では、ホストの Java 仮想マシン* にインストールされたオプションパッケージの中から目的のオプションパッケージ (またはその他のライブラリ) の実装が見つからなかった場合に検索する URL を列挙します。この相対 URL には、アプリケーションまたはオプションパッケージが必要とするライブラリまたはリソースが含まれる JAR ファイルとディレクトリを含めることができます。「/」で終わらない URL は、JAR ファイルを参照しているものとみなされます。次に例を示します。
Class-Path: servlet.jar infobus.jar acme/beans.jar images/JAR ファイルのマニフェストで指定できる Class-Path ヘッダーは 1 つだけです。
現時点では、セキュリティー上の理由により、URL は JAR ファイルのコードベースから相対的に指定する必要があります。したがって、リモートオプションパッケージは、アプリケーションと同じコードベースを元にして指定します。
それぞれの相対 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 ファイルが実際に必要になったときまで開かれません。
<java-home>\lib\ext [Microsoft Windows] <java-home>/lib/ext [Solaris OS, Linux]
ここで <java-home> は、ランタイムソフトウェアのインストール先ディレクトリ (JRE のトップレベルディレクトリまたは JDK の jre ディレクトリ) を指します。
システムプロパティー java.ext.dirs を使用すると、インストール型オプションパッケージを置く場所を指定できます。このプロパティーには、インストール型オプション機能を検索するディレクトリを指定できます。複数のディレクトリを指定する場合は、File.pathSeparatorChar で区切ります。java.ext.dirs のデフォルトの設定値は、上に示したインストール型オプション機能の標準のディレクトリになっています。Java 6 以降に改良されたデフォルト設定では、同じシステムにインストールされたすべての JRE (Java 6 以降) によって共有されるプラットフォーム固有のディレクトリへのパスが付けられます。
%SystemRoot%\Sun\Java\lib\ext [Microsoft Windows] /usr/java/packages/lib/ext [Linux] /usr/jdk/packages/lib/ext [Solaris OS]
さらに、インストール型オプションパッケージは、1 つ以上の共有ライブラリ (.dll ファイルなど) と実行可能ファイルを含んでいます。そのあと、<arch> が表示されますが、実際には命令セットアーキテクチャーの名前、たとえば sparc、sparcv9、i386、amd64 などが続きます。これらは 2 つの場所のいずれかにインストールされます。最初に検索されるのは次のディレクトリです。
<java-home>\bin [Microsoft Windows] <java-home>/lib/<arch> [Solaris OS, Linux]
次に検索される拡張機能ディレクトリは、Java 6 以降にのみ適用されます。Java パッケージと同様、ネイティブライブラリはすべての Java 6 とそれ以降の JRE によって共有されるディレクトリにインストールできます。
%SystemRoot%\Sun\Java\bin [Microsoft Windows] /usr/java/packages/lib/<arch> [Linux] /usr/jdk/packages/lib/<arch> [Solaris OS]
ネイティブコードが含まれるオプションパッケージは、信頼できるコードか信頼できないコードかにかかわらず、実行時にネットワークコードにより仮想マシンにダウンロードすることはできません。ネイティブコードが含まれ、ネットワークアプリケーションとともにバンドルされているオプションパッケージは、JDK または JRE にインストールする必要があります。
デフォルトでは、この標準のディレクトリに置かれたインストール型オプションパッケージは信頼できます。つまり、このディレクトリに置かれたインストール型拡張機能には、コアプラットフォームクラス (rt.jar 内のクラス) の場合と同じ特権が与えられます。このデフォルトの特権は、システムポリシーファイル (<java-home>/jre/lib/security/java.policy) で指定されていますが、適切なポリシーファイルのエントリ (「JDK でのアクセス権」を参照) を追加すれば、特定のオプションパッケージにオーバーライドできます。
なお、信頼できるエンティティーによりインストール型オプションパッケージの JAR ファイルに署名が付けられている場合、そのオプションパッケージには、署名を付けたエンティティーに関連付けられている特権が与えられます。
JAR ファイル内のパッケージをシールした場合、そのパッケージ内で定義されているすべてのクラスは、同一の JAR ファイルが元になっていなければなりません。そうでない場合は、SecurityException がスローされます。
JAR ファイルをシールした場合、その JAR ファイルで定義されているすべてのパッケージは、特別に設定をオーバーライドしないかぎり、シールされます。
パッケージをシールするかどうかは、マニフェスト属性 Sealed で指定します。このマニフェスト属性は、true か false の値をとります。大文字小文字は区別されません。次に例を示します。
Name: javax/servlet/internal/ Sealed: trueこのように指定すると、javax.servlet.internal がシールされ、このパッケージに含まれるすべてのクラスは同一の JAR ファイルからロードされなければなりません。
この属性が指定されていない場合は、パッケージのシール属性は、そのパッケージが含まれる JAR ファイルのシール属性と同じになります。
JAR ファイルをシールするかどうかは、上と同じマニフェストヘッダー Sealed で指定します。このマニフェストヘッダーも、同じく true か false の値をとります。次に例を示します。
Sealed: trueこのように指定すると、このアーカイブに含まれるすべてのパッケージは、マニフェストエントリの中で Sealed 属性により明示的に設定をオーバーライドしないかぎり、シールされます。
この属性が指定されていない場合は、下位互換性を保つため、その JAR ファイルはシールされていないものとみなされます。このあと、システムはシール情報を見るため、パッケージのヘッダーのチェックを継続します。
パッケージをシールすると、パッケージ保護されたメンバーへのアクセスは、同一の JAR ファイルが元になるパッケージで定義されているクラスに制限されるため、パッケージのシールはセキュリティーの上でも重要です。
パッケージシーリングのチェックは、ダウンロード型オプションパッケージだけでなくインストール型オプションパッケージについても行われ、違反があった場合は SecurityException がスローされます。また、null パッケージはシールできないので、シールすべきクラスはその独自のパッケージ内に置く必要があります。
<java-home>/lib/security/java.policyデフォルトのポリシーは、インストール型オプションパッケージが、コアプラットフォームの一部である場合と同じように動作できるようにするためのものです。これは、インストール型オプションパッケージがネイティブコードをロードするという一般的な必要性に基づいています。
Java Security Model は、インストール型オプションパッケージのコードが信頼できないコードから呼び出された場合のために、ある種の安全策を提供しています。しかし、オプションパッケージのコードが特権ブロックを使用する場合は必ず、セキュリティー上の危険性がないかどうかコードを十分に確認する必要があります。
リモートからロードされるオプションパッケージで、正常な動作のため、アクセスチェックが行われるシステムサービス (ファイル入出力など) を使用する必要があるものについては、信頼できるエンティティーによる署名が付けられたものであるか、信頼できる場所からロードされたものでなければなりません。
Java プラットフォームのセキュリティー機能を利用するためのオプションパッケージやアプリケーションのコードを記述する方法の詳細については、Java セキュリティードキュメントを参照してください。
* この Web サイトで使用されている用語「Java 仮想マシン」または「JVM」は、Java プラットフォーム用の仮想マシンを表します。