java
コマンドは、Javaアプリケーションを起動するため、Javaランチャと呼ばれています。Javaランチャが呼び出されると、ユーザーおよびユーザーの環境(クラス・パスやブート・クラス・パスなど)から入力が収集され、仮想マシン(VM)に接続され、一部のブートストラップ経由で開始されます。残りの作業は、Java仮想マシン(JVM)で実行されます。
この章では次のトピックについて説明します。
JVMは、次の順序でクラスを検索してロードします。
Javaプラットフォームを構成するブートストラップ・クラス(rt.jar
とその他のいくつかの重要なJARファイル内のクラスを含む)。
Java拡張機能メカニズムを使用する拡張機能クラス。これらのクラスはJARファイルとしてバンドルされ、extensions
ディレクトリに配置されています。
開発者とサード・パーティによって定義され、拡張機能メカニズムを利用しないユーザー・クラス。これらのクラスの位置は、コマンド行で-classpath
オプションを使用する(推奨)か、CLASSPATH
環境変数を使用して指定します。「クラス・パスの設定」を参照してください。
実際には、3つの検索パスをまとめて1つのシンプルなクラス・パスが構成されます。これは、以前に使われていた平坦なクラス・パスに似ていますが、現在のモデルは次のように改善されました。
ブートストラップ・クラスを誤って隠したり省略したりする間違いが比較的少なくなる。
通常は、ユーザー・クラスの位置を指定するだけで済む。ブートストラップ・クラスと拡張機能クラスは、自動的に検出される。
ツールのクラスは、現在は別のアーカイブ(tools.jar
)に分けられており、ユーザー・クラス・パスに含まれている場合にのみ使用できる(「Javaランタイムがブートストラップ・クラスを検索する方法」を参照)。
ブートストラップ・クラスは、Java SEを実装しているクラスです。ブートストラップ・クラスは、jre/lib
ディレクトリのrt.jar
ファイルとその他のいくつかのJARファイルに格納されています。これらのアーカイブは、システム・プロパティsun.boot.class.path
に格納されているブートストラップ・クラス・パスの値によって指定されます。このシステム・プロパティは参照専用なので、直接修正しないでください。ブートストラップ・クラス・パスの再定義が必要になることはほとんどありません。まれに、別のコア・クラスのセットを使用する必要が生じた場合には、非標準オプション-Xbootclasspath
を使用して行うことができます。
JDKツールを実装するクラスは、ブートストラップ・クラスとは別のアーカイブに分けられています。ツール・アーカイブは、JDKの/lib/tools.jar
ファイルです。開発ツールは、起動ツールを呼び出すときに、このアーカイブをユーザー・クラス・パスに追加します。ただし、この追加後のユーザー・クラス・パスは、ツールを実行するためだけに使用されます。ソース・コードを処理するツール(javac
コマンドとjavadoc
コマンド)は、追加後のクラス・パスではなく、元のクラス・パスを使用します。詳細は、「javacコマンドとjavadocコマンドがクラスを検索する方法」を参照してください。
拡張機能クラスは、Javaプラットフォームを拡張するクラスです。拡張機能ディレクトリjre/lib/ext
内の.jar
ファイルはすべて拡張機能とみなされ、Java拡張機能フレームワークを使用してロードされます。拡張機能ディレクトリ内の圧縮されていないクラス・ファイルは、見つけることができません。JARファイルまたはZipファイル内に含まれている必要があります。拡張機能ディレクトリの位置を変更するためのオプションはありません。
jre/lib/ext
ディレクトリに複数のJARファイルが含まれており、次の例に示すように、これらのファイルに同じ名前のクラスが含まれている場合、実際にロードされるクラスは未定義になります。
smart-extension1_0.jar
にクラスsmart.extension.Smart
が含まれる
smart-extension1_1.jar
にクラスsmart.extension.Smart
が含まれる
ユーザー・クラスを探すために、ランチャはユーザー・クラス・パス(クラス・ファイルを含むディレクトリ、JARファイル、Zipファイルのリスト)を参照します。
クラス・ファイルは、そのクラスの完全修飾名が反映されたサブパス名を持ちます。たとえば、クラスcom.mypackage.MyClass
がmyclasses
に格納されている場合、myclasses
はユーザー・クラス・パスに含まれている必要があり、クラス・ファイルへのフル・パスは、Oracle Solarisの場合は/myclasses/com/mypackage/MyClass.class
、Windowsの場合は\myclasses\com\mypackage\MyClass.class
でなければいけません。
クラスがmyclasses.jar
という名前のアーカイブ内に格納されている場合、myclasses.jar
はユーザー・クラス・パスに含まれている必要があり、クラス・ファイルはアーカイブ内に、Windowsの場合はcom/mypackage/MyClass.class
、Oracle Solarisの場合はcom\mypackage\MyClass.class
として格納されていなければいけません。
ユーザー・クラス・パスは文字列として指定され、Oracle Solarisではクラス・パスのエントリがコロン(:)で区切られ、Windowsシステムではエントリがセミコロン(;)で区切られます。Javaランチャは、ユーザー・クラス・パス文字列をシステム・プロパティjava.class.path
に書き込みます。この値は、次のいずれかのソースから取得されます。
ユーザー・クラス・ファイルが現在のディレクトリ内またはその下にあるすべてのクラス・ファイルであることを表すデフォルト値*.*
。
デフォルト値をオーバーライドするCLASSPATH
環境変数の値。
デフォルト値とCLASSPATH
値の両方をオーバーライドする-cp
または-classpath
コマンド行オプションの値。
-jar
オプションで指定されたJARアーカイブにそのマニフェスト内のClass-Path
エントリが含まれる場合は、これによって他のすべての値がオーバーライドされます。このオプションを使用する場合、すべてのユーザー・クラスは指定されたアーカイブからのものである必要がある。
JARファイルには通常、マニフェスト(そのJARファイルの内容をリストしたファイル)が含まれます。マニフェストには、そのJARファイルからクラスをロードしているときにのみクラス・パスをさらに展開するJARクラス・パスを定義できます。JARクラス・パスによってアクセスされるクラスは、次の順序で検索されます。
一般に、JARクラス・パスのエントリによって参照されるクラスは、JARファイルの一部であるかのように検索される。JARクラス・パス内のJARファイルは、クラス・パス内でそのJARファイルより前にあるエントリの後、かつ、そのJARファイルより後にあるエントリの前に検索される。
JARクラス・パスが、すでに検索されたJARファイル(たとえば、拡張機能またはクラス・パス内でそれより前に記述されているJARファイル)を指している場合は、そのJARファイルが再度検索されることはない。この最適化により効率が向上し、循環検索が回避される。このタイプのJARファイルは、クラス・パスの前の方で認識された時点で検索される。
JARファイルが拡張機能としてインストールされている場合は、そのJARファイルによって定義されるすべてのJARクラス・パスは無視される。拡張機能が必要とするクラスはすべて、JDKの一部であるか、拡張機能としてインストールされているとみなされる。
javac
コマンドとjavadoc
コマンドは、次の2とおりの方法でクラス・ファイルを使用します。
実行するために、javac
コマンドとjavadoc
コマンドは様々なクラス・ファイルをロードする必要がある。
処理対象のソース・コードを処理するために、javac
コマンドとjavadoc
コマンドは、ソース・コードで使用されているオブジェクト型の情報を取得する必要がある。
ソース・コード参照を解決するために使用されるクラス・ファイルのほとんどは、javac
コマンドとjavadoc
コマンドの実行に使用されるのと同じクラス・ファイルです。ただし、次のようないくつかの重要な例外があります。
javac
コマンドとjavadoc
コマンドはどちらも、javac
コマンドまたはjavadoc
コマンドの実装とは無関係なクラスやインタフェースへの参照を解決することがしばしばある。参照されているユーザー・クラスとインタフェースに関する情報は、クラス・ファイルまたはソース・コード・ファイル(あるいはその両方)の形式で存在する。
tools.jar
ファイル内のツール・クラスは、javac
コマンドとjavadoc
コマンドを実行するためだけに使用される。ツール・クラスは、tools.jar
ファイルがユーザー・クラス・パス内にある場合を除いて、ソース・コード参照を解決するためには使用されない。
プログラマは、代替Javaプラットフォーム実装を使用して、ブート・クラスまたは拡張機能クラス参照を解決したい場合がある。javac
コマンドとjavadoc
コマンドはどちらも、-bootclasspath
および-extdirs
オプションでこれをサポートする。これらのオプションを使用しても、javac
コマンドまたはjavadocコマンド自体の実行に使用されるクラス・ファイル・セットは変更されない。
参照されるクラスがクラス・ファイルとソース・ファイルの両方で定義されている場合、javadoc
コマンドは常にソース・ファイルを使用します。javadoc
コマンドは、ソース・ファイルをコンパイルしません。同じ状況の場合に、javac
コマンドはクラス・ファイルを使用しますが、古くなったと判断されるクラス・ファイルは自動的に再コンパイルします。自動再コンパイルの規則については、
のドキュメントで説明されています。javac
デフォルトでは、javac
コマンドとjavadoc
コマンドは、ユーザー・クラス・パスからクラス・ファイルとソース・コード・ファイルの両方を検索します。-sourcepath
オプションが指定されている場合、javac
コマンドとjavadoc
コマンドは、指定されたソース・ファイル・パスでのみソース・ファイルを検索します。ただし、クラス・ファイルは同様にユーザー・クラス・パスから検索されます。
クラスまたはインタフェースを使用するためには、クラス・ローダーでロードする必要があります。特定のクラス・ローダーの使い方により、そのクラス・ローダーに関連するセキュリティ・ポリシーが決定されます。
プログラムでは、クラス・ローダー・オブジェクトのloadClass
メソッドを呼び出すことにより、クラスまたはインタフェースをロードできます。ただし通常は、プログラムは参照することによってクラスやインタフェースをロードします。これにより内部クラス・ローダーが呼び出されます(セキュリティ・ポリシーを拡張機能およびユーザー・クラスに適用できます)。セキュリティ・ポリシーが有効になっていなかった場合でも、すべてのクラスが信頼されます。セキュリティ・ポリシーが有効な場合でも、ブートストラップ・クラスには適用されません(常に信頼されます)。
有効になっているときは、セキュリティ・ポリシーはシステムおよびユーザー・ポリシー・ファイルによって設定されます。JavaプラットフォームSDKはシステム・ポリシー・ファイルをインクルードします(拡張機能クラスに信頼ステータスを付与し、ユーザー・クラスに基本的な制限を適用します)。
セキュリティ・ポリシーの有効化または設定については、「セキュリティ機能」を参照してください。
注: 以前のリリースのJava SEで使われていたセキュリティ・プログラミング技法の中には、最新リリースのクラス・ロード・モデルと互換性のないものがあります。