Java Platform, Standard Editionツール・リファレンス
目次      

1 クラスの検索方法

javaコマンドは、Javaアプリケーションを起動するため、Javaランチャと呼ばれています。Javaランチャが呼び出されると、ユーザーおよびユーザーの環境(クラス・パスやブート・クラス・パスなど)から入力が収集され、仮想マシン(VM)に接続され、一部のブートストラップ経由で開始されます。残りの作業は、Java仮想マシン(JVM)で実行されます。

この章では次のトピックについて説明します。

Javaランタイムがクラスを検索する方法

JVMは、次の順序でクラスを検索してロードします。

  1. Javaプラットフォームを構成するブートストラップ・クラス(rt.jarとその他のいくつかの重要なJARファイル内のクラスを含む)。

  2. Java拡張機能メカニズムを使用する拡張機能クラス。これらのクラスはJARファイルとしてバンドルされ、extensionsディレクトリに配置されています。

  3. 開発者とサード・パーティによって定義され、拡張機能メカニズムを利用しないユーザー・クラス。これらのクラスの位置は、コマンド行で-classpathオプションを使用する(推奨)か、CLASSPATH環境変数を使用して指定します。「クラス・パスの設定」を参照してください。

実際には、3つの検索パスをまとめて1つのシンプルなクラス・パスが構成されます。これは、以前に使われていた平坦なクラス・パスに似ていますが、現在のモデルは次のように改善されました。

  • ブートストラップ・クラスを誤って隠したり省略したりする間違いが比較的少なくなる。

  • 通常は、ユーザー・クラスの位置を指定するだけで済む。ブートストラップ・クラスと拡張機能クラスは、自動的に検出される。

  • ツールのクラスは、現在は別のアーカイブ(tools.jar)に分けられており、ユーザー・クラス・パスに含まれている場合にのみ使用できる(「Javaランタイムがブートストラップ・クラスを検索する方法」を参照)。

Javaランタイムがブートストラップ・クラスを検索する方法

ブートストラップ・クラスは、Java SEを実装しているクラスです。ブートストラップ・クラスは、jre/libディレクトリのrt.jarファイルとその他のいくつかのJARファイルに格納されています。これらのアーカイブは、システム・プロパティsun.boot.class.pathに格納されているブートストラップ・クラス・パスの値によって指定されます。このシステム・プロパティは参照専用なので、直接修正しないでください。ブートストラップ・クラス・パスの再定義が必要になることはほとんどありません。まれに、別のコア・クラスのセットを使用する必要が生じた場合には、非標準オプション-Xbootclasspathを使用して行うことができます。

JDKツールを実装するクラスは、ブートストラップ・クラスとは別のアーカイブに分けられています。ツール・アーカイブは、JDKの/lib/tools.jarファイルです。開発ツールは、起動ツールを呼び出すときに、このアーカイブをユーザー・クラス・パスに追加します。ただし、この追加後のユーザー・クラス・パスは、ツールを実行するためだけに使用されます。ソース・コードを処理するツール(javacコマンドとjavadocコマンド)は、追加後のクラス・パスではなく、元のクラス・パスを使用します。詳細は、「javacコマンドとjavadocコマンドがクラスを検索する方法」を参照してください。

Javaランタイムがユーザー・クラスを検索する方法

ユーザー・クラスを探すために、ランチャはユーザー・クラス・パス(クラス・ファイルを含むディレクトリ、JARファイル、Zipファイルのリスト)を参照します。

クラス・ファイルは、そのクラスの完全修飾名が反映されたサブパス名を持ちます。たとえば、クラスcom.mypackage.MyClassmyclassesに格納されている場合、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エントリが含まれる場合は、これによって他のすべての値がオーバーライドされます。このオプションを使用する場合、すべてのユーザー・クラスは指定されたアーカイブからのものである必要がある。

JavaランタイムがJARクラス・パス・クラスを検索する方法

JARファイルには通常、マニフェスト(そのJARファイルの内容をリストしたファイル)が含まれます。マニフェストには、そのJARファイルからクラスをロードしているときにのみクラス・パスをさらに展開するJARクラス・パスを定義できます。JARクラス・パスによってアクセスされるクラスは、次の順序で検索されます。

  1. 一般に、JARクラス・パスのエントリによって参照されるクラスは、JARファイルの一部であるかのように検索される。JARクラス・パス内のJARファイルは、クラス・パス内でそのJARファイルより前にあるエントリの後、かつ、そのJARファイルより後にあるエントリの前に検索される。

  2. JARクラス・パスが、すでに検索されたJARファイル(たとえば、拡張機能またはクラス・パス内でそれより前に記述されているJARファイル)を指している場合は、そのJARファイルが再度検索されることはない。この最適化により効率が向上し、循環検索が回避される。このタイプのJARファイルは、クラス・パスの前の方で認識された時点で検索される。

  3. JARファイルが拡張機能としてインストールされている場合は、そのJARファイルによって定義されるすべてのJARクラス・パスは無視される。拡張機能が必要とするクラスはすべて、JDKの一部であるか、拡張機能としてインストールされているとみなされる。

javacコマンドとjavadocコマンドがクラスを検索する方法

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で使われていたセキュリティ・プログラミング技法の中には、最新リリースのクラス・ロード・モデルと互換性のないものがあります。

目次      

Copyright © 1993, 2020, Oracle and/or its affiliates. All rights reserved.