クラスの検索方法 |
SDK ツール |
Java 起動ツール java は、Java Virtual Machine (VM) を起動します。VM は、次の順序でクラスを検索してロードします。
- ブートストラップクラス - Java プラットフォームを構成するクラス。
rt.jar
とi18n.jar
内のクラスが含まれる
- 拡張機能クラス - Java 拡張機能機構を使用するクラス。拡張機能用ディレクトリに
.jar
ファイルとしてバンドルされている
- ユーザクラス - 開発者とサードパーティにより定義された、拡張機能の機構を利用しないクラス。これらのクラスの位置は、コマンド行で -classpath オプションを使用する (推奨) か、CLASSPATH 環境変数を使って指定する。クラスパスの設定については、それぞれ Windows または Solaris 用のページを参照)
実際には、この 3 つの検索パスは 1 つのクラスパスに結合されます。これは、以前に使われていた「平坦な」クラスパスに似ていますが、現在のモデルには重要な相違点がいくつかあります。
- ブートストラップクラスを、誤って「隠し」たり省いたりすることが比較的少なくなる
- 通常は、ユーザクラスの位置を指定するだけで済む。ブートストラップクラスと拡張機能クラスは、「自動的」に検出される
- ツールのクラスは、現在は別のアーカイブ (tools.jar) に分けられており、ユーザクラスパスに含まれている場合にだけ使用できる (簡単な説明を後述する)
Java 起動ツールがブートストラップクラスを検索する方法
ブートストラップクラスは、Java 2 プラットフォームを実装しているクラスです。ブートストラップクラスは、
jre/lib
ディレクトリのrt.jar
とi18n.jar
の 2 つのアーカイブ内に格納されています。アーカイブは、システムプロパティsun.boot.class.path
に格納されているブートストラップクラスパスの値によって指定されます。このシステムプロパティは参照専用で、直接修正してはなりません。ブートストラップクラスのパスの再定義が必要になることは、ほとんどありません。まれに、別のコアクラスのセットを使用する必要が生じた場合には、非標準のオプション -Xbootclasspath を使ってブートストラップクラスのパスを再定義することができます。
Java 2 SDK ツールを実装したクラスはブートストラップクラスとは別のアーカイブに分けられているので、注意してください。 ツールのアーカイブは SDK の
/lib/tools.jar
ファイルです。開発ツールはこのアーカイブを、起動ツールを呼び出すときにユーザクラスパスに追加します。ただし、この追加後のユーザクラスパスは起動ツールの実行時にだけ使用されます。ソースコードの処理を行うツール javac と javadoc は、追加後のクラスパスではなく元のクラスパスを使用します。(詳細は、次の「javac と javadoc がクラスを検索する方法」を参照)Java 起動ツールが拡張機能クラスを検索する方法
拡張機能クラスは、Java プラットフォームを継承するクラスです。拡張機能ディレクトリ jre/lib/ext 内の
.jar
ファイルはすべて拡張機能とみなされ、Java 拡張機能機構を使ってロードされます。拡張機能ディレクトリ内でどれにも属さないクラスファイルは、見つけることができません。これらのファイルは、.jar ファイル (または .zip ファイル) 内に含まれている必要があります。拡張機能ディレクトリの位置を変更するためのオプションはありません。
Java 起動ツールがユーザクラスを検索する方法
ユーザクラスは、Java プラットフォームの上に構築されるクラスです。ユーザクラスを探すために、起動ツールはユーザクラスパス (ディレクトリのリスト、JAR アーカイブ、クラスファイルの入った ZIP アーカイブ) を参照します。
クラスには、そのクラスの完全指定された名前を反映したサブパス名があります。たとえば、クラス
com.mypackage.MyClass
が/myclasses
内に格納されている場合、/myclasses
はユーザクラスパス内に含まれていなければならず、そのクラスファイルへの絶対パスは/myclasses/com/mypackage/MyClass.class
でなければなりません。 クラスがmyclasses.jar
という名前のアーカイブ内に格納されている場合、ユーザクラスパスにはmyclasses.jar
が含まれていなければならず、クラスファイルはアーカイブ内にcom/mypackage/MyClass.class
として格納されていなければなりません。ユーザクラスパスは文字列として指定され、Solaris ではクラスパスのエントリはコロン (
:
) で区切られ、Win32 システムではエントリはセミコロン (;
) で区切られます。java 起動ツールは、ユーザクラスパスの文字列をシステムプロパティjava.class.path
に書き込みます。この値は、次のどれかから取得可能です。
- デフォルト値 (「
.
」)。 この場合、ユーザクラスファイルは、現在のディレクトリ内 (パッケージ内なら、現在のディレクトリ以下) のすべてのクラスファイルである
- CLASSPATH 環境変数の値。 デフォルト値を無効にする
- -cp または -classpath コマンド行オプションの値。 デフォルト値と CLASSPATH の値の両方を無効にする
- -jar オプションで指定された JAR アーカイブ。 他のすべての値を無効にする。このオプションを使用すると、すべてのユーザクラスは指定されたアーカイブから検索される
Java 起動ツールが JAR-class-path クラスを検索する方法
JAR ファイルには、通常、「マニフェスト」が含まれます。マニフェストは JAR ファイルの内容のリストです。 マニフェストは、クラスパスをさらに継承する JAR-class-path を定義できます (ただし、パスを継承するのは、その JAR ファイルからクラスをロードしている間だけ)。JAR-class-path がアクセスするクラスは、次の順序で検索されます。
- 通常、JAR-class-path エントリによって参照されるクラスは、JAR ファイルの一部であるかのように検索される。JAR-class-path 内の JAR ファイルが検索される順序は、クラスパス内のそれより前のエントリのあとで、それより後ろのエントリの前になる
- ただし、JAR-class-path が、すでに検索された JAR ファイル (たとえば、拡張機能、またはクラスパス内で前に記述されている JAR ファイル) を指している場合は、その JAR ファイルがもう一度検索されることはありません。(この最適化により効率が向上し、巡回検索が回避される。)このような JAR ファイルは、クラスパスの前の方で認識された時点で検索される
- JAR ファイルが JDK の
ext
サブディレクトリ内に拡張機能としてインストールされている場合は、そのファイルが定義する JAR-class-path は無視される。拡張機能が必要とするクラスはすべて SDK の一部である、またはそれ自体が拡張機能としてインストールされていると仮定される
javac と javadoc の各ツールは、2 つの異なった方法でクラスファイルを使用します。
- すべての Java アプリケーションと同様に、javac と javadoc を実行するためには、さまざまなクラスファイルをロードする必要がある
- 動作の基盤であるソースコードを処理するためには、javac と javadoc はソースコードで使用されるオブジェクト型の情報を取得する必要がある
ソースコードの参照を解決するために使用されるクラスファイルは、ほとんどは javac と javadoc の実行に使用されるのと同じファイルです。ただし、重要な例外があります。
- javac と javadoc のどちらも、javac または javadoc の実装とは無関係なクラスとインタフェースへの参照を解決することがしばしばある。参照されるユーザクラスとインタフェースに関する情報は、クラスファイルとソースコードファイルのどちらかまたは両方の形式で存在する
tools.jar
内のツールクラスは、javac と javadoc を実行するためにだけ使用される。ツールクラスは、tool.jar
がユーザクラスパス内にない限りは、ソースコードの参照を解決するためには使用されない
- 別の Java プラットフォーム実装を使って、ブートクラスや拡張機能クラスの参照を解決したい場合がある。javac と javadoc のどちらも、-bootclasspath と -extdirs の各オプションによって、これをサポートする。これらのオプションを使用しても、javac または javadoc 自体の実行に使用されるクラスファイルのセットは変更されない
参照されているクラスがクラスファイルとソースファイルの両方で定義されている場合、javadoc は常にソースファイルを使用します (javadoc はソースファイルをコンパイルしない)。同じ場合に、javac はクラスファイルを使用しますが、古くなったと判断したクラスファイルを自動的に再コンパイルします。自動再コンパイルの規則については、Windows または Solaris 用の javac ドキュメントで説明しています。
デフォルトでは、javac と javadoc はユーザクラスパスでクラスファイルとソースコードファイルの両方を検索します。-sourcepath オプションを指定すると、javac と javadoc は、指定されたソースファイルパスだけを検索します。
クラスまたはインタフェースを使用するためには、クラスローダでロードする必要があります。特定のクラスローダの使い方により、そのクラスローダに関連するセキュリティポリシーが決定されます。
プログラムは、クラスローダオブジェクトの loadClass メソッドを呼び出すことにより、クラスまたはインタフェースをロードすることができます。しかし通常は、プログラムは単に参照によってクラスやインタフェースをロードします。クラスやインタフェースを参照すると、内部クラスローダが呼び出されます。 内部クラスローダは、セキュリティポリシーを拡張機能とユーザクラスに適用することができます。セキュリティポリシーが有効になっていない場合、すべてのクラスは「信頼できる」と判断されます。セキュリティポリシーが有効な場合でも、ブートストラップクラスにはセキュリティポリシーは適用されないので、常に「信頼できる」とみなされます。
セキュリティポリシーは、有効な場合に、システムポリシーファイルとユーザポリシーファイルによって設定されます。Java 2 SDK にはシステムポリシーファイルがあり、このポリシーファイルは拡張機能クラスには「信頼できる」状態を認可し、ユーザクラスには基本的なアクセス制限を課します。
セキュリティポリシーの設定と有効化については、「セキュリティ」を参照してください。
注: Java 1.1 プラットフォームで使われるセキュリティプログラミング技法の中には、Java 2 プラットフォームのクラスロードモデルとの互換性がないものがあります。