―Javaプログラミングの前提知識―
2001/5/12
クラスパス(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. ブートクラスパスを検索する
最初に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は、標準クラスライブラリはブートクラスパスで、アプリケーションが利用する追加ライブラリはエクステンションメカニズムで、クラスファイルを検索するので、クラスパスには、アプリケーションのクラスの場所を指定するだけで済むようになりました。
- 実運用の障害対応時間比較に見る、ログ管理基盤の効果 (2017/5/9)
ログ基盤の構築方法や利用方法、実際の案件で使ったときの事例などを紹介する連載。今回は、実案件を事例とし、ログ管理基盤の有用性を、障害対応時間比較も交えて紹介 - Chatwork、LINE、Netflixが進めるリアクティブシステムとは何か (2017/4/27)
「リアクティブ」に関連する幾つかの用語について解説し、リアクティブシステムを実現するためのライブラリを紹介します - Fluentd+Elasticsearch+Kibanaで作るログ基盤の概要と構築方法 (2017/4/6)
ログ基盤を実現するFluentd+Elasticsearch+Kibanaについて、構築方法や利用方法、実際の案件で使ったときの事例などを紹介する連載。初回は、ログ基盤の構築、利用方法について - プログラミングとビルド、Androidアプリ開発、Javaの基礎知識 (2017/4/3)
初心者が、Java言語を使ったAndroidのスマホアプリ開発を通じてプログラミングとは何かを学ぶ連載。初回は、プログラミングとビルド、Androidアプリ開発、Javaに関する基礎知識を解説する。
|
|