―Javaプログラミングの前提知識―

前田俊行
2001/5/12
Javaプログラミング
ワンポイントレクチャーについて

   クラスパス(class path)を正しく使う
  ―Java VMのクラスファイル検索機構―

今回の内容
クラスパスの指定方法
クラスパスに指定できるクラスファイルの場所

Java VMがクラスファイルを検索する仕組み

 クラスパスとは、Javaアプリケーションを実行するときに、Java Virtual Machine(Java VM)がどの“場所”からクラスファイルを読み込めばよいかを、指定するためのものです。 基本的には、Java VMは、アプリケーションを実行するために必要なクラスファイルをクラスパスに指定された“場所”から読み込みます(本当は、もう少し複雑な仕組みがJava VMにはありますが、それについては、後半で説明します)。

 クラスパスの指定方法

 Java VMにクラスパスを指定するには、Java VMを実行するときに、次のように入力します。

java -classpath <場所> <実行するクラス名>

 “-classpath <場所>”が、実際にクラスパスを指定している部分です。

 クラスパスに複数の“場所”を指定するには、“場所”の間を記号“;”(セミコロン)で区切ります。Java VMは、クラスパスの先頭に指定された“場所”から、クラスファイルを見つけるまで、順番に“場所”を検索していきます。 例えば、クラスパスに、“場所”としてディレクトリC:\test\classesとディレクトリC:\tmpを指定して、クラスWordProcessorを実行するには、次のように入力します。

java -classpath C:\test\classes;C:\tmp WordProcessor

 このとき、Java VMは、まず、ディレクトリC:\test\classesを検索し、もし見つからなければ、次にディレクトリC:\tmpを検索します。クラスパスを検索した結果、クラスファイルWordProcessor.classが見つかれば、それを実行します。

 もし、クラスパスに指定された“場所”に、実行しようとしているクラスファイルを発見できなければ、Java VMは次のようなエラーメッセージを表示して、クラスファイルが見つからなかったことを報告します。

Exception in thread "main" java.lang.NoClassDefFoundError: クラス名

 クラス名の部分には、実際に指定したクラス名が表示されます。クラスファイルを実行しようとして上のようなエラーメッセージが表示された場合は、クラスパスを誤って指定している可能性が高いです。

 クラスパスを指定するにあたり、最も間違えやすいのは、カレントディレクトリを指定し忘れることです。Java VMは、カレントディレクトリを特別扱いしません。そのため、カレントディレクトリをクラスパスに指定していなければ、カレントディレクトリ内の検索は行われません。ただし、クラスパスを-classpathを用いて明示的に指定しなければ、Java VMはクラスパスを自動的にカレントディレクトリに指定します。つまり、

java -classpath . WordProcessor

と入力するのと、

java WordProcessor

と入力するのは、まったく同じです。

 クラスパスに指定できるクラスファイルの“場所”

 すでに説明したように、Java VMはクラスパスに指定された“場所”から、クラスファイルを検索しようとします。“場所”には、前節で説明したように、ディレクトリを指定できます。

 それに加え、Java VMでは、ディレクトリ以外にも特別なファイルを“場所”として指定できます。特別なファイルとは、具体的には、ZIPファイルとJARファイルの2種類のファイルです。

 ZIPファイルとは、複数のファイルを、1つのファイルにまとめたものです。Java VMはZIPファイル中のクラスファイルを、読み込むことができます。

 JARファイルとは、基本的にはZIPファイルと同じく、複数のファイルを1つのファイルにまとめたものです。ちなみに、JARとはJava ARchiveの略です(JARファイルには単にファイルをまとめるだけでなく、ほかにもいろいろな機能がありますが、ここでは説明しません)。

 クラスパスにZIPファイルやJARファイルを指定するには、単にそのファイル名を指定します。例えば、クラスパスにディレクトリC:\tmpとJARファイルC:\libraries\Library.jarを指定して実行するには、次のように入力します。

java -classpath C:\tmp;C:\libraries\Library.jar <実行するクラス名>


 Java VMがクラスファイルを検索する仕組み

 ここまでで、基本的なクラスパスの仕組みとクラスパスの指定の仕方について説明しましたが、Java VMのクラスファイルの読み込みは、実はもっと複雑な仕組みになっています。ここではその仕組みについて説明します。

 Java VMは次のように、クラスを3段階に分けて検索します。

  1. ブートクラスパスを検索する
  2. エクステンション(拡張)ディレクトリ中のJARファイルを検索する
  3. “クラスパス”を検索する

1. ブートクラスパスを検索する
 最初にJava VMがクラスを検索するのが、ブートクラスパスです。ブートクラスパスには例えば、java.lang.Objectやjava.net.URLClassLoaderやjava.io.OutputStreamなどの、システム標準クラスライブラリのクラスが含まれます。

 前節で説明したクラスパスとブートクラスパスは異なるものです。 つまり、クラスパスをいくら変更しても、ブートクラスパスには影響しません。ブートクラスパスを変更する方法については、「javaコマンドを使いこなす」を参照してください。

2. エクステンション(拡張)ディレクトリ中のJARファイルを検索する
 ブートクラスパス中にクラスを発見できなかった場合、Java VMは次にエクステンションディレクトリ中のJARファイルを検索します。Javaでは、標準クラスライブラリ以外に、クラスライブラリをシステムに追加するための仕組みが存在します。これをインストールエクステンションメカニズムと呼びます。このインストールエクステンションメカニズムで追加するクラスライブラリのJARファイルを置くディレクトリが、エクステンションディレクトリです。エクステンションメカニズムについては、「クラスパスを使わないでクラスライブラリを利用する」を参照してください。

3. “クラスパス”を検索する
 ブートクラスパスにもエクステンションディレクトリにもクラスファイルが存在しなかった場合、Java VMは前節で説明した、いわゆる“クラスパス”を検索します。通常のJavaアプリケーションのクラスはこの段階でJava VMに読み込まれます。

 古いバージョンのJava VMは、現在のように3段階ではなく、いわゆる“クラスパス”のみを用いて、すべてのクラスを検索していました。そのため、クラスパスを設定するときには、アプリケーションのクラスの場所だけでなく、標準クラスライブラリの場所や、アプリケーションが利用する追加クラスライブラリの場所も指定しなければなりませんでした。現在のJava VMは、標準クラスライブラリはブートクラスパスで、アプリケーションが利用する追加ライブラリはエクステンションメカニズムで、クラスファイルを検索するので、クラスパスには、アプリケーションのクラスの場所を指定するだけで済むようになりました。

Javaプログラミング・ワンポイントレクチャー INDEX





Java Agile フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Java Agile 記事ランキング

本日 月間