Java 起動ツール java は、Java Virtual Machine (VM) を起動します。VM は、次の順序でクラスを検索してロードします。
- ブートストラップクラス - Java プラットフォームを構成するクラス。
rt.jar
とi18n.jar
内のクラスが含まれる
- 拡張機能クラス - Java 拡張機能機構を使用するクラス。拡張機能用ディレクトリに
.jar
ファイルとしてバンドルされている
- ユーザクラス - 開発者とサードパーティにより定義された、拡張機能機構を利用しないクラス。これらのクラスの場所は、コマンド行で -classpath オプションを使用する (推奨) か、CLASSPATH 環境変数を使って指定する
実際には、この 3 つの検索パスは 1 つのクラスパスに結合されます。これは、以前に使われていた「フラットな」クラスパスに似ていますが、現在のモデルには重要な相違点がいくつかあります。
- ブートストラップクラスを、誤って「隠し」たり省いたりすることが比較的少なくなる
- 通常、ユーザクラスの位置だけを指定すればよい。ブートストラップクラスと拡張機能クラスは、「自動的」に検出される
- ツールのクラスは、現在は別のアーカイブ (tools.jar) に分けられているため、ユーザクラスパスに含まれている場合にだけ使用できる (簡単な解説を後述する)。
Java 起動ツールがブートストラップクラスを検索する方法
ブートストラップクラスは、 Java 1.2 プラットフォームを実装しているクラスです。ブートストラップクラスは、
/jdk1.2/jre/lib
ディレクトリのrt.jar
とi18n.jar
の 2 つのアーカイブ内に格納されています。アーカイブは、システムプロパティsun.boot.class.path
に格納されているブートストラップクラスパスの値によって指定されます。このシステムプロパティは参照専用なため、直接修正してはいけません。ブートストラップクラスのパスの再定義が必要になることは、ほとんどありません。まれに、別のコアクラスのセットを使用する必要が生じた場合には、非標準のオプション -Xbootclasspath を使ってブートストラップクラスのパスを再定義することができます。
JDK 開発ツールを実装したクラスは、ブートストラップクラスとは別のアーカイブに分けられているので、注意してください。ツールのアーカイブは
/jdk1.2/lib/tools.jar
です。開発ツールは、起動ツールを呼び出すときに、このアーカイブをユーザクラスパスに追加します。ただし、この追加後のユーザクラスパスは、起動ツールの実行時にだけ使用されます。ソースコードの処理を行うツール javac と javadoc は、追加後のクラスパスではなく元のクラスパスを使用します (詳細については、次の 「javac と javadoc がクラスを検索する方法」を参照)。Java 起動ツールが拡張機能クラスを検索する方法
拡張機能クラスは、Java プラットフォームを継承するクラスです。拡張機能ディレクトリ内の
.jar
ファイルはすべて拡張機能とみなされ、Java 拡張機能機構を使ってロードされます。拡張機能ディレクトリの位置を変更するためのオプションはありません。
Java 起動ツールがユーザクラスを検索する方法
ユーザクラスは、Java プラットフォームの上に構築されるクラスです。ユーザクラスを探すために、起動ツールはユーザクラスパス (ディレクトリのリスト、JAR アーカイブ、クラスファイルの入った ZIP アーカイブ) を参照します。
クラスには、そのクラスの完全指定された名前を反映したサブパス名があります。たとえば、クラス
com.mypackage.MyClass
が/myclasses
内に格納されている場合、/myclasses
はユーザクラスパス内に含まれていなければならず、そのクラスファイルへの絶対パスは/myclasses/com/mypackage/MyClass.class
でなければなりません。クラスがmyclasses.jar
という名前のアーカイブ内に格納されている場合、ユーザクラスパスにはmyclasses.jar
が含まれていなければならず、クラスファイルはアーカイブ内にcom/mypackage/MyClass.class
として格納されていなければなりません。Solaris では、ユーザクラスパスは文字列として指定され、クラスパスのエントリはコロン (
:
) で区切られます。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 は無視されます。拡張機能が必要とするクラスはすべて JDK の一部であるか、あるいはそれ自体が拡張機能としてインストールされていると仮定されます。
oldjava 起動ツールは Java 拡張機能機構をサポートしません。次の場合の、旧バージョンとの互換性維持のためにだけ用意されています。
- 1.1 スタイルのセキュリティマネージャを実装しているアプリケーションを実行する場合。1.1 スタイルのセキュリティマネージャは、1.2 のクラスロード手法と互換性がない
- ロードするクラスが、1.2 のクラス構造と互換性のない方法 (オブファスケータなどにより) で作成または操作されている場合
(これらの問題の詳細については migration.html を参照してください。)
oldjava 起動ツールは、ブートストラップとユーザクラスを 1 つのパスに結合します。oldjava でクラスパスを指定する方法は、2 つあります。
- CLASSPATH 環境変数にユーザパスを指定する。ユーザパスは、あらかじめ定義されているブートストラップクラスパスに追加される
- -cp または -classpath コマンド行オプションで完全なクラスパスを指定する。CLASSPATH の値とあらかじめ定義されたブートストラップクラスパスの両方が無視される
結合されたクラスパスは、システムプロパティ
java.class.path
に格納されます。
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 はクラスファイルを使用しますが、古くなったと判断したクラスファイルを自動的に再コンパイルします。自動再コンパイルの規則は、javac ツールのドキュメントに説明されています。
デフォルトでは、javac と javadoc はユーザクラスパスでクラスファイルとソースコードファイルの両方を検索します。-sourcepath オプションを指定すると、javac と javadoc は、指定されたソースファイルパスだけを検索します。
クラスまたはインタフェースを使用するためには、クラスローダでロードする必要があります。特定のクラスローダの使い方により、そのクラスローダに関連するセキュリティポリシーが決定されます。
プログラムは、クラスローダオブジェクトの loadClass メソッドを呼び出すことにより、クラスまたはインタフェースをロードすることができます。しかし通常は、プログラムは単に参照によってクラスやインタフェースをロードします。クラスやインタフェースを参照すると、内部クラスローダが呼び出されます。内部クラスローダは、セキュリティポリシーを拡張機能とユーザクラスに適用することができます。セキュリティポリシーが有効になっていない場合、すべてのクラスは「信頼できる」と判断されます。セキュリティポリシーが有効な場合でも、ブートストラップクラスにはセキュリティポリシーは適用されないので、常に「信頼できる」とみなされます。
セキュリティポリシーは、有効な場合は、システムポリシーファイルとユーザポリシーファイルによって設定されます。JDK ソフトウェアにはシステムポリシーファイルがあり、このポリシーファイルは拡張機能クラスには「信頼できる」状態を認可し、ユーザクラスには基本的なアクセス制限を課します。
セキュリティポリシーの設定と有効化については、「セキュリティ」を参照してください。
注: Java 1.1 プラットフォームで使われるセキュリティプログラミング技法の中には、1.2 のクラスロードモデルとの互換性がないものがあります。既存のコードを一時的にサポートするために、今回のリリースには 1.1 のクラスロードモデルを使用する oldjava 起動ツールが含まれています。