サーチ…


前書き

クラスパスは、Javaランタイムがクラスおよびリソースを探す場所をリストします。クラスパスは、以前にコンパイルされた外部依存関係を見つけるためにJavaコンパイラによっても使用されます。

備考

Javaクラスのロード

JVM(Java Virtual Machine)は、クラスが必要なときにクラスをロードします(これは遅延ロードと呼ばれます)。使用されるクラスの場所は、次の3つの場所で指定されます。

  1. Java Class Libraryに必要なものやその依存関係など、Java Platformで必要なものが最初に読み込まれます。
  2. 拡張クラスは次にロードされます(つまり、 jre/lib/ext/
  3. クラスパスを介してユーザー定義のクラスがロードされます。

クラスは、 java.lang.ClassLoaderサブタイプであるクラスを使用してロードされjava.lang.ClassLoader 。これについては、このトピック「 クラスローダー」で詳しく説明しています。

クラスパス

クラスパスは、ユーザ定義のクラスとパッケージの場所を指定するJVMまたはコンパイラによって使用されるパラメータです。これは、これらの例のほとんどの場合と同様にコマンドラインで、または環境変数( CLASSPATH )を使用して設定できます。

クラスパスを指定するさまざまな方法

クラスパスを設定する方法は3つあります。

  1. これは、 CLASSPATH環境変数を使用して設定できます。

     set CLASSPATH=...         # Windows and csh
     export CLASSPATH=...      # Unix ksh/bash
    
  2. コマンドラインで次のように設定することができます

     java -classpath ...
     javac -classpath ...
    

    -classpath (または-cp )オプションは、 CLASSPATH環境変数よりも優先されることに注意してください。

  3. 実行可能な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ファイル、それ以外の場合は現在のディレクトリです。

関連:

ディレクトリ内のすべてのJARをクラスパスに追加する

ディレクトリ内のすべてのJARをクラスパスに追加する場合は、クラスパスのワイルドカード構文を使用してこれを簡潔に行うことができます。例えば:

 someFolder/*

これは、 someFolderディレクトリのすべてのJARファイルとZIPファイルをクラスパスに追加するようにJVMに指示します。この構文は、実行可能なJARファイルのマニフェストファイル内の-cp引数、 CLASSPATH環境変数、またはClass-Path属性で使用できます。クラスパスの設定:クラスパスワイルドカードの例と警告

ノート:

  1. Classpathワイルドカードは、Java 6で初めて導入されました。以前のバージョンのJavaでは、「*」はワイルドカードとして扱われません。
  2. ""の前後に他の文字を置くことはできません。例えば ​​"someFolder / .jar"はワイルドカードではありません。
  3. ワイルドカードは、接尾辞 ".jar"または ".JAR"のファイルにのみ一致します。 ZIPファイルは無視され、別の接尾辞を持つJARファイルも無視されます。
  4. ワイルドカードは、ディレクトリ自体のJARファイルにのみ一致し、サブディレクトリには一致しません。
  5. 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など)を読み込むと便利です。この目的のために、 ClassClassLoader使用できます。

次のプロジェクト構造があるとします。

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.classcom.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.classSomeClass$2.classなど

クラスパスの意味:検索の仕組み

クラスパスの目的は、JVMにクラスやその他のリソースを見つける場所を伝えることです。クラスパスと検索プロセスの意味は絡み合っています。

クラスパスは、リソースを探すための一連の場所を指定する検索パスの一形式です。標準クラスパスでは、これらの場所は、ホストファイルシステムのディレクトリ、JARファイル、またはZIPファイルのいずれかです。いずれの場合も、場所は検索される名前空間のルートです。

クラスパス上でクラスを検索するための標準的な手順は次のとおりです。

  1. クラス名を相対クラスファイルパス名RPマップします。クラス名のクラスファイル名へのマッピングは、別の場所で説明されています。

  2. クラスパス内の各エントリEについて:

    • エントリがファイルシステムディレクトリの場合:
      • Eを基準にしてRP解決し、絶対パス名AP指定します。
      • APが既存のファイルのパスであるかどうかをテストします。
      • はいの場合は、そのファイルからクラスをロードします
    • エントリがJARまたはZIPファイルの場合:
      • JAR / ZIPファイルインデックスのRPを参照してください。
      • 対応するJAR / ZIPファイル・エントリが存在する場合は、そのエントリからクラスをロードします。

クラスパス上のリソースを検索する手順は、リソースパスが絶対パスか相対パスかによって異なります。絶対リソースパスの場合、手順は上記のとおりです。 Class.getResourceまたはClass.getResourceAsStreamを使用して解決される相対的なリソースパスの場合、クラスパッケージのパスは検索の前に付加されます。

(標準のJavaクラスローダーによって実装されたプロシージャーであることに注意してください。カスタムクラスローダーは検索を別々に実行することがあります)。

ブートストラップクラスパス

通常のJavaクラスローダーは、拡張機能とアプリケーションクラスパスをチェックする前に、まずブートストラップクラスパスでクラスを探します。デフォルトでは、ブートストラップクラスパスは、 "rt.jar"ファイルとJREインストールで提供されるその他の重要なJARファイルで構成されています。これらは、標準のJava SEクラスライブラリのすべてのクラスと、さまざまな「内部」実装クラスを提供します。

通常の状況下では、これに心配する必要はありません。デフォルトでは、 javajavacなどのコマンドは、ランタイムライブラリの適切なバージョンを使用します。

非常にときどき、標準ライブラリのクラスの代替バージョンを使用して、Javaランタイムの通常の動作を変更する必要があります。たとえば、通常の方法で回避できないランタイムライブラリに「ショーストッパー」バグが発生する可能性があります。このような状況では、変更されたクラスを含むJARファイルを作成し、それをJVMを起動するブートストラップクラスパスに追加することができます。

javaコマンドでは、ブートストラップクラスパスを変更するために次の-Xオプションを提供しています。

  • -Xbootclasspath:<path>は、現在のブートクラスパスを指定されたパスに置き換えます。
  • -Xbootclasspath/a:<path>は、指定されたパスを現在のブートクラスパスに追加します。
  • -Xbootclasspath/p:<path>は、指定されたパスを現在のブートクラスパスの先頭に-Xbootclasspath/p:<path>ます。

Javaクラス(その他)を置き換えるまたは上書きするためにbootclasspathオプションを使用する場合、技術的にJavaを変更していることに注意してください。コードを配布する場合、ライセンスの影響があるかもしれません 。 (Java Binary Licenseの利用規約を参照し、弁護士に相談してください)。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow