クラスパスは、Java 実行環境がクラスおよびその他のソースファイルを検索するパスです。クラス検索パス (「クラスパス」という短い名前が一般的) の設定は、JDK ツールを呼び出すときに -classpath オプションを付ける方法 (推奨される方法) か、CLASSPATH 環境変数を設定する方法により行います。-classpath オプションが推奨されているのは、アプリケーションごとに個別に設定できるので、ほかのアプリケーションに影響を与えたり、ほかのアプリケーションからこの値が変更されたりすることがないためです。
% sdkTool -classpath classpath1:classpath2...
-または-
% setenv CLASSPATH classpath1:classpath2...
以下にそれぞれの意味を示します。
java、javac、javadoc、apt など) です。JDK ツールのリストは、「JDK ツールとユーティリティー」を参照してください。:classpath2複数のパスエントリを設定する場合は、コロンで区切ります。
デフォルトのクラスパスは、現在のディレクトリです。このデフォルトは、CLASSPATH 変数を設定したり、-classpath コマンド行オプションを使用したりするとオーバーライドされます。そのため、検索パスに現在のディレクトリを含める場合には、新しい設定に「.」を含める必要があります。
ディレクトリおよびアーカイブ (.zip または .jar ファイル) 以外のクラスパスエントリは、無視されます。
クラスパスは JDK ツールおよび Java アプリケーションに対して、サードパーティー製のクラスおよびユーザー定義のクラス、つまり拡張機能や Java プラットフォームの一部ではないクラスを探す位置を通知します。クラスパスでは、javac コンパイラでコンパイルしたすべてのクラスが検出される必要があります。それらのクラスを簡単に検出できるように、デフォルトは現在のディレクトリになっています。
JDK、JVM、およびその他の JDK ツールでは、Java プラットフォーム (ブートストラップ) のクラス、拡張機能のクラス、そしてクラスパスという順序でクラスが検索されます。検索の詳細については、「クラスの検索方法」を参照してください。ほとんどのアプリケーションのクラスライブラリでは、拡張機能メカニズムを利用しているはずです。クラスパスを設定する必要があるのは、(a) 現在のディレクトリまたはそのサブディレクトリ内にないクラスや、(b) 拡張機能メカニズムによって指定された位置にないクラスをロードする必要がある場合だけです。
旧バージョンの JDK をアップグレードしている場合は、不要になった CLASSPATH 環境変数の設定が起動設定に含まれていることがあります。このため、classes.zip など、アプリケーション固有ではない設定は、すべて削除する必要があります。Java 仮想マシンを使うサードパーティー製アプリケーションの中には、使用するライブラリをインクルードするために CLASSPATH 環境変数を変更するものがあります。このような設定は残しておいてもかまいません。
クラスパスを変更するには、JVM またはほかの JDK ツールを起動するときに JDK ツールの -classpath オプションを使用するか、または CLASSPATH 環境変数を使用します。CLASSPATH 環境変数を設定するよりも、-classpath オプションを使用することをお勧めします。アプリケーションごとに個別に設定できるので、ほかのアプリケーションに影響を与えたり、ほかのアプリケーションからこの値が変更されたりすることがないためです。
クラスは、ディレクトリ (フォルダ) またはアーカイブファイルに格納できます。Java プラットフォームのクラスは、rt.jar に格納されています。アーカイブの詳細およびクラスパスの機能については、「クラスパスとパッケージ名について」を参照してください。
重要: 一部の旧バージョンの JDK ソフトウェアでは、デフォルトのクラスパスに <jdk-dir>/classes エントリが含まれています。このディレクトリは、JDK ソフトウェアが使用するためのものです。アプリケーションのクラスのためには使用しないでください。アプリケーションのクラスは、JDK のディレクトリ階層ではない、外部のディレクトリに置いてください。そうすれば、新しい JDK をインストールしたときに、アプリケーションのクラスを再インストールする必要がなくなります。旧バージョンとの互換性を確保するため、<jdk-dir>/classes ディレクトリをクラスライブラリとして使用するアプリケーションも、現在のバージョンでは実行できます。ただし、将来のバージョンでも実行できるという保証はありません。
Java ツール java、jdb、javac、javah には、-classpath オプションがあります。このオプションは、ツールの実行中に、CLASSPATH 環境変数によって指定された 1 つまたは複数のパスを別のパスに置き換えます。クラスパスの設定を変更する場合は、この方法をお勧めします。各アプリケーションが、ほかのアプリケーションに影響を与えずに、自分に必要なクラスパスを設定できるからです。
実行時ツール java には、-cp オプションもあります。このオプションは、-classpath の省略形です。
ごく特殊なケースのために、java と javac には、ツール自体のクラスライブラリ検索用パスを変更するためのオプションがあります。ただし、ほとんどのユーザーはこのオプションを使う必要はありません。
前述のとおり、クラスパスを変更するには、通常、-classpath コマンド行オプションを使用します。ここでは、必要な場合に CLASSPATH 環境変数を設定する方法と、旧バージョンのインストール時から残っている設定を解除する方法を説明します。
csh では、setenv コマンドを使って CLASSPATH 環境変数を修正します。コマンドの形式は、次のとおりです。
setenv CLASSPATH path1:path2
sh では、次のコマンドを使って CLASSPATH 環境変数を修正します。
CLASSPATH = path1:path2:...
export CLASSPATH
CLASSPATH 環境変数に設定されている値が正しくない場合や、起動ファイルやスクリプトで間違ったパスを設定している場合、csh では、次のコマンドを使用して CLASSPATH の設定を解除します。
unsetenv CLASSPATH
sh では、次のコマンドを使用します。
unset CLASSPATH
これらのコマンドは、現在のシェルについてのみ、CLASSPATH の設定を解除します。次回以降のセッションでも CLASSPATH が正しく設定されるようにするには、起動設定を削除または修正する必要があります。
CLASSPATH 環境変数がシステムの起動時に設定されている場合、その設定場所は、実行しているシェルによって異なります。
| シェル | 起動スクリプト |
|---|---|
| csh、tcsh | .cshrc ファイルで setenv コマンドを調べます。 |
| sh、ksh | .profile ファイルで export コマンドを調べます。 |
ベース名のワイルドカード文字 * を含むクラスパスエントリは、ディレクトリ内の拡張子 .jar または .JAR を持つすべてのファイルのリストを指定したものと同等であると見なされます。たとえば、クラスパスエントリ foo/* は foo というディレクトリ内のすべての JAR ファイルを指定します。* だけから成るクラスパスエントリは、カレントディレクトリ内のすべての JAR ファイルのリストに展開されます。ファイルは、隠されている (つまり、名前が「.」で始まる) かどうかに関係なく考慮されます。
* を含むクラスパスエントリは、クラスファイルには一致しません。単一のディレクトリ foo 内でクラスファイルと JAR ファイルの両方に一致するには、foo:foo/* または foo/*:foo を使用します。選択された順序により、foo 内のクラスおよびリソースが foo 内の JAR ファイルの前に (またはその逆で) ロードされるかどうかが決まります。
サブディレクトリは再帰的に検索されません。たとえば、foo/* では foo 内の JAR ファイルだけを検索し、foo/bar、foo/baz などは検索しません。
ディレクトリ内の JAR ファイルが展開されたクラスパスで列挙される順序は指定されず、プラットフォームにより、あるいは同じマシン上でも時間によって異なる場合があります。うまく構成されたアプリケーションは、特定の順序に依存しないようにすべきです。特定の順序が必要な場合は、クラスパスで JAR ファイルを明示的に列挙できます。
ワイルドカードの展開は早期に行われ、クラスのロード処理自体の間ではなく、プログラムの main メソッドの呼び出しの前に行われます。ワイルドカードを含む入力クラスパスの各要素は、指定したディレクトリ内の JAR ファイルを列挙して生成された要素のシーケンス (空の場合もある) によって置き換えられます。たとえば、ディレクトリ foo に a.jar、b.jar、および c.jar が含まれる場合、クラスパス foo/* は foo/a.jar:foo/b.jar:foo/c.jar に展開され、文字列はシステムプロパティー java.class.path の値になります。
CLASSPATH 環境変数は、-classpath (または -cp) コマンド行オプションと異なって扱われることはありません。つまり、すべての場合ワイルドカードが使えます。ただし、クラスパスワイルドカードは Class-Path JAR マニフェストのヘッダーでは使えません。
Java のクラスはパッケージとして編成され、各パッケージはファイルシステム内のディレクトリにマッピングされています。ただし、ファイルシステムとは異なり、パッケージ名を指定するときは、パッケージ名の一部ではなく必ず全体を指定します。たとえば、java.awt.Button のパッケージ名は、必ず java.awt と指定する必要があります。
たとえば、Java Runtime が utility.myapp パッケージ内の Cool.class という名前のクラスを探すように設定する場合を考えてみましょう。そのディレクトリへのパスが /java/MyClasses/utility/myapp であれば、/java/MyClasses を含むようにクラスパスを設定します。
このアプリケーションを実行するには、次の JVM コマンドを使用します。
% java -classpath /java/MyClasses utility.myapp.Cool
アプリケーションを実行するとき、JVM はクラスパスの設定を使って、utility.myapp パッケージ内に定義されている、Cool クラスが使用するほかのクラスを検索します。
このコマンドには完全なパッケージ名を指定してください。たとえば、クラスパスに /java/MyClasses/utility が含まれるように設定したうえで、コマンド java myapp.Cool を使用することはできません。そのクラスが見つからないためです。
なぜこのようなクラスのパッケージ名が認められないのか疑問に思うかもしれません。それは、クラスのパッケージ名はそのクラスの一部であり、変更できないからです。パッケージ名を変更するには、クラスをコンパイルし直さなければなりません。
注:パッケージ指定のメカニズムに関連した興味深い事例として、「同じパッケージに属する複数のクラスファイルが、実際には別々のディレクトリに存在する」という状況が可能です。この場合、各クラスのパッケージ名は同じですが、それぞれのファイルへのパスは、クラスパス内の別々のディレクトリで始まります。
クラスが /java/MyClasses/utility/myapp のようなディレクトリ (フォルダ) に格納されている場合、クラスパスのエントリは、パッケージ名の先頭の要素が格納されているディレクトリを指します。この場合は、パッケージ名が utility.myapp なので、/java/MyClasses を指します。
ただし、クラスがアーカイブファイル (.zip ファイルまたは .jar ファイル) 内に格納されている場合、クラスパスのエントリは、その .zip ファイルまたは .jar ファイルへのパスとなり、これらのファイル名も含めて指定します。たとえば、.jar ファイル内のクラスライブラリを使用するには、次のようなコマンドを使用します。
% java -classpath /java/MyClasses/myclasses.jar utility.myapp.Cool
ディレクトリ /java/MyClasses 内のクラスファイルと /java/OtherClasses 内のクラスを検索するには、クラスパスを次のように設定します。
% java -classpath /java/MyClasses:/java/OtherClasses ...
2 つのパスはコロンで区切ってください。
複数のクラスパスエントリを指定する順序は重要です。Java インタプリタは、クラスパス変数に指定されている順序でディレクトリを調べてクラスを探します。上の例では、Java インタプリタは最初に /java/MyClasses ディレクトリ内から必要なクラスを探します。このディレクトリ内に該当するクラス名を持つクラスが見つからなかった場合にだけ、インタプリタは /java/OtherClasses ディレクトリ内を検索します。