Java Language
クラスパス
サーチ…
前書き
備考
Javaクラスのロード
JVM(Java Virtual Machine)は、クラスが必要なときにクラスをロードします(これは遅延ロードと呼ばれます)。使用されるクラスの場所は、次の3つの場所で指定されます。
- Java Class Libraryに必要なものやその依存関係など、Java Platformで必要なものが最初に読み込まれます。
- 拡張クラスは次にロードされます(つまり、
jre/lib/ext/
) - クラスパスを介してユーザー定義のクラスがロードされます。
クラスは、 java.lang.ClassLoader
サブタイプであるクラスを使用してロードされjava.lang.ClassLoader
。これについては、このトピック「 クラスローダー」で詳しく説明しています。
クラスパス
クラスパスは、ユーザ定義のクラスとパッケージの場所を指定するJVMまたはコンパイラによって使用されるパラメータです。これは、これらの例のほとんどの場合と同様にコマンドラインで、または環境変数( CLASSPATH
)を使用して設定できます。
クラスパスを指定するさまざまな方法
クラスパスを設定する方法は3つあります。
これは、
CLASSPATH
環境変数を使用して設定できます。set CLASSPATH=... # Windows and csh export CLASSPATH=... # Unix ksh/bash
コマンドラインで次のように設定することができます
java -classpath ... javac -classpath ...
-classpath
(または-cp
)オプションは、CLASSPATH
環境変数よりも優先されることに注意してください。実行可能なJARファイルのクラスパスは、
MANIFEST.MF
Class-Path
要素を使用して指定します。Class-Path: jar1-name jar2-name directory-name/jar3-name
これは、JARファイルが次のように実行されている場合にのみ適用されることに注意してください。
java -jar some.jar ...
この実行モードでは、JARファイルに
Class-Path
要素がない場合でも、-classpath
オプションとCLASSPATH環境変数は無視されます。
クラスパスが指定されていない場合、デフォルトのクラスパスはjava -jar
を使用する場合は選択されたJARファイル、それ以外の場合は現在のディレクトリです。
関連:
- https://docs.oracle.com/javase/tutorial/deployment/jar/downman.html
- http://docs.oracle.com/javase/7/docs/technotes/tools/windows/classpath.html
ディレクトリ内のすべてのJARをクラスパスに追加する
ディレクトリ内のすべてのJARをクラスパスに追加する場合は、クラスパスのワイルドカード構文を使用してこれを簡潔に行うことができます。例えば:
someFolder/*
これは、 someFolder
ディレクトリのすべてのJARファイルとZIPファイルをクラスパスに追加するようにJVMに指示します。この構文は、実行可能なJARファイルのマニフェストファイル内の-cp
引数、 CLASSPATH
環境変数、またはClass-Path
属性で使用できます。クラスパスの設定:クラスパスワイルドカードの例と警告
ノート:
- Classpathワイルドカードは、Java 6で初めて導入されました。以前のバージョンのJavaでは、「*」はワイルドカードとして扱われません。
- ""の前後に他の文字を置くことはできません。例えば "someFolder / .jar"はワイルドカードではありません。
- ワイルドカードは、接尾辞 ".jar"または ".JAR"のファイルにのみ一致します。 ZIPファイルは無視され、別の接尾辞を持つJARファイルも無視されます。
- ワイルドカードは、ディレクトリ自体のJARファイルにのみ一致し、サブディレクトリには一致しません。
- JARファイルのグループがワイルドカードエントリと一致すると、クラスパス上での相対的な順序は指定されません。
クラスパスのパス構文
クラスパスは、ディレクトリパス名、JARまたはZIPファイルパス名、またはJAR / ZIPワイルドカード指定である一連のエントリです。
コマンドラインで指定されたクラスパス(
-classpath
)または環境変数としては、以下のようにエントリを区切る必要があります;
(セミコロン)は、Windows上の文字、または:
他のプラットフォーム上(コロン)文字(その上のLinux、UNIX、MacOSXのと)。JARファイルの
MANIFEST.MF
内のClass-Path
要素では、単一のスペースを使用してエントリを区切ります。
時には、クラスパスエントリにスペースを埋め込む必要がある
クラスパスがコマンドラインで指定されている場合は、適切なシェル引用符を使用するだけです。例えば:
export CLASSPATH="/home/user/My JAR Files/foo.jar:second.jar"
(詳細は、使用するコマンドシェルによって異なる場合があります)。
クラスパスがJARファイルの "MANIFEST.MF"ファイルで指定されている場合は、URLエンコーディングを使用する必要があります。
Class-Path: /home/user/My%20JAR%20Files/foo.jar second.jar
動的クラスパス
場合によっては、ネイティブコードがあり、JARのサブセットを選択する必要がある場合など、フォルダからすべてのJARを追加するだけでは不十分です。この場合、2つのmain()
メソッドが必要です。最初のクラスローダーはクラスローダーを作成し、このクラスローダーを使用して2番目のmain()
メソッドを呼び出します。
ここでは、ご使用のプラットフォーム用の正しいSWTネイティブJARを選択し、アプリケーションのJARをすべて追加してから、実際のmain()
メソッドを呼び出します。クロスプラットフォームJava SWTアプリケーションの作成
クラスパスからリソースをロードする
JAR内にパッケージ化されているリソース(イメージ、テキストファイル、プロパティ、KeyStoreなど)を読み込むと便利です。この目的のために、 Class
とClassLoader
使用できます。
次のプロジェクト構造があるとします。
program.jar
|
\-com
\-project
|
|-file.txt
\-Test.class
また、 Test
クラスからfile.txt
の内容にアクセスしたいとします。クラスローダーに尋ねることで、そうすることができます:
InputStream is = Test.class.getClassLoader().getResourceAsStream("com/project/file.txt");
クラスローダを使用することにより、リソース(各パッケージ)の完全修飾パスを指定する必要があります。
あるいは、Testクラスオブジェクトに直接問い合わせることもできます
InputStream is = Test.class.getResourceAsStream("file.txt");
クラスオブジェクトを使用すると、パスはクラス自体に相対的です。 Test.class
はcom.project
パッケージにあり、 file.txt
と同じですが、パスを何も指定する必要はありません。
しかし、次のように、クラスオブジェクトから絶対パスを使用することはできます:
is = Test.class.getResourceAsStream("/com/project/file.txt");
クラス名をパス名にマッピングする
標準のJavaツールチェーン(およびそれらと相互運用するように設計されたサードパーティのツール)は、クラスの名前をファイルのパス名やそれを表す他のリソースにマッピングするための特定のルールを持っています。
マッピングは次のとおりです
- デフォルトパッケージのクラスの場合、パス名は単純なファイル名です。
- 名前付きパッケージ内のクラスの場合、パッケージ名のコンポーネントはディレクトリにマップされます。
- ネストされたネストされたクラスとインナークラスの場合、クラス名を
$
文字で結合することによってファイル名コンポーネントが形成されます。 - 匿名の内部クラスでは、名前の代わりに数字が使用されます。
これを次の表に示します。
クラス名 | ソースパス名 | クラスファイルのパス名 |
---|---|---|
SomeClass | SomeClass.java | SomeClass.class |
com.example.SomeClass | com/example/SomeClass.java | com/example/SomeClass.class |
SomeClass.Inner | ( SomeClass.java ) | SomeClass$Inner.class |
内部クラスのSomeClass | ( SomeClass.java ) | SomeClass$1.class 、 SomeClass$2.class など |
クラスパスの意味:検索の仕組み
クラスパスの目的は、JVMにクラスやその他のリソースを見つける場所を伝えることです。クラスパスと検索プロセスの意味は絡み合っています。
クラスパスは、リソースを探すための一連の場所を指定する検索パスの一形式です。標準クラスパスでは、これらの場所は、ホストファイルシステムのディレクトリ、JARファイル、またはZIPファイルのいずれかです。いずれの場合も、場所は検索される名前空間のルートです。
クラスパス上でクラスを検索するための標準的な手順は次のとおりです。
クラス名を相対クラスファイルパス名
RP
マップします。クラス名のクラスファイル名へのマッピングは、別の場所で説明されています。クラスパス内の各エントリ
E
について:- エントリがファイルシステムディレクトリの場合:
-
E
を基準にしてRP
解決し、絶対パス名AP
指定します。 -
AP
が既存のファイルのパスであるかどうかをテストします。 - はいの場合は、そのファイルからクラスをロードします
-
- エントリがJARまたはZIPファイルの場合:
- JAR / ZIPファイルインデックスの
RP
を参照してください。 - 対応するJAR / ZIPファイル・エントリが存在する場合は、そのエントリからクラスをロードします。
- JAR / ZIPファイルインデックスの
- エントリがファイルシステムディレクトリの場合:
クラスパス上のリソースを検索する手順は、リソースパスが絶対パスか相対パスかによって異なります。絶対リソースパスの場合、手順は上記のとおりです。 Class.getResource
またはClass.getResourceAsStream
を使用して解決される相対的なリソースパスの場合、クラスパッケージのパスは検索の前に付加されます。
(標準のJavaクラスローダーによって実装されたプロシージャーであることに注意してください。カスタムクラスローダーは検索を別々に実行することがあります)。
ブートストラップクラスパス
通常のJavaクラスローダーは、拡張機能とアプリケーションクラスパスをチェックする前に、まずブートストラップクラスパスでクラスを探します。デフォルトでは、ブートストラップクラスパスは、 "rt.jar"ファイルとJREインストールで提供されるその他の重要なJARファイルで構成されています。これらは、標準のJava SEクラスライブラリのすべてのクラスと、さまざまな「内部」実装クラスを提供します。
通常の状況下では、これに心配する必要はありません。デフォルトでは、 java
、 javac
などのコマンドは、ランタイムライブラリの適切なバージョンを使用します。
非常にときどき、標準ライブラリのクラスの代替バージョンを使用して、Javaランタイムの通常の動作を変更する必要があります。たとえば、通常の方法で回避できないランタイムライブラリに「ショーストッパー」バグが発生する可能性があります。このような状況では、変更されたクラスを含むJARファイルを作成し、それをJVMを起動するブートストラップクラスパスに追加することができます。
java
コマンドでは、ブートストラップクラスパスを変更するために次の-X
オプションを提供しています。
-
-Xbootclasspath:<path>
は、現在のブートクラスパスを指定されたパスに置き換えます。 -
-Xbootclasspath/a:<path>
は、指定されたパスを現在のブートクラスパスに追加します。 -
-Xbootclasspath/p:<path>
は、指定されたパスを現在のブートクラスパスの先頭に-Xbootclasspath/p:<path>
ます。
Javaクラス(その他)を置き換えるまたは上書きするためにbootclasspathオプションを使用する場合、技術的にJavaを変更していることに注意してください。コードを配布する場合、ライセンスの影響があるかもしれません 。 (Java Binary Licenseの利用規約を参照し、弁護士に相談してください)。