Java
 Computer >> コンピューター >  >> プログラミング >> Java

クラスがJavaに存在するのに、なぜClassNotFoundExceptionが発生するのですか?

Javaでクラスをロードする際、クラスローダーが指定されたパスでクラスを見つけられないと、ClassNotFoundExceptionが発生します。

この例外は、Javaプログラムの実行時や、ClassクラスのforName()メソッド、あるいはClassLoaderクラスのloadClass()メソッドを使って明示的にクラスをロードする際に起こる可能性があります。これらのメソッドはクラス名を表す文字列を受け取り、指定されたクラスをロードします。

ClassNotFoundExceptionを防ぐためのポイント

これらのメソッドにクラス名を渡す際は、以下の点に注意する必要があります。

  • メソッドに渡すクラス名が正確であること(パッケージ名も含めて完全修飾名で指定する)。
  • 指定したクラス(パッケージを含む)がカレントディレクトリに存在するか、そのパスが環境変数classpathに登録されていること。

例:Sampleクラスの作成とコンパイル

ここでは、ディレクトリD://Sampleというクラスを作成し、以下のようにコンパイルした場合を想定します。

package myPackage.example;
public class Sample {
    static {
        System.out.println("Sampleクラスが正常にロードされました.........");
    }
}

コンパイル方法

D:\>javac -d . Sample.java

このコマンドを実行すると、カレントディレクトリにmyPackage.exampleパッケージが作成され、その中にSampleクラスの.classファイルが生成されます。したがって、このクラスをロードする際には、同じディレクトリ構成を保ったまま、完全修飾クラス名をClass.forName()またはloadClass()に渡す必要があります。

例1:パッケージ名のスペルミスによる例外

次のコードでは、パッケージ名を誤って「myPackage.exampl」と記述しています。

public class ClassNotFoundExample {
    public static void main(String args[]) {
        try {
            Class.forName("myPackage.exampl.Sample");
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        }
    }
}

実行結果(例外)

このプログラムを実行すると、パッケージ名のスペルが間違っているため、以下のような例外がスローされます。

D:\>java ClassNotFoundExample
java.lang.ClassNotFoundException: myPackage.exampl.Sample
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(Unknown Source)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Unknown Source)
    at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
    at java.base/java.lang.Class.forName0(Native Method)
    at java.base/java.lang.Class.forName(Unknown Source)
    at ClassNotFoundExample.main(ClassNotFoundExample.java:4)

例2:classpathが設定されていない場合の例外

別のディレクトリから特定のクラスにアクセスしたい場合は、以下のいずれかに対してクラスパスを設定する必要があります。

  • .classファイルを含むフォルダ(最上位のパッケージ)
  • クラスを含むjarファイル

今度はスペルミスを修正し、ディレクトリE://にあるJavaファイルからクラスをロードしてみます。

public class ClassNotFoundExample {
    public static void main(String args[]) {
        try {
            Class.forName("myPackage.example.Sample");
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        }
    }
}

実行結果(例外)

しかし、この場合でも同じ例外が発生します。これは、対象クラスの.classファイルを含むパッケージ(またはそれを含むjarファイル)が、カレントディレクトリにも環境変数classpathのパス一覧にも存在しないためです。

E:\>java ClassNotFoundExample
java.lang.ClassNotFoundException: myPackage.example.Sample
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(Unknown Source)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Unknown Source)
    at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
    at java.base/java.lang.Class.forName0(Native Method)
    at java.base/java.lang.Class.forName(Unknown Source)
    at ClassNotFoundExample.main(ClassNotFoundExample.java:4)

解決策:classpathを設定して実行する

この状況を解決するには、必要なクラスを含むパッケージが格納されているディレクトリ、つまり「D://」をclasspathに設定してからプログラムを実行します。

E:\>javac ClassNotFoundExample.java
E:\>java ClassNotFoundExample
Sampleクラスが正常にロードされました.........

このように、ClassNotFoundExceptionはクラス自体が存在しない場合だけでなく、クラス名の記述ミスやclasspathの設定漏れによっても発生します。例外に遭遇した際は、まず完全修飾クラス名が正しいか、そして対象クラスへのパスがclasspathに含まれているかを確認しましょう。

  1. JavaにおけるCursorクラスの役割とは?マウスカーソル制御の基本を解説

    JavaのCursorクラスとはCursorクラスは、Objectクラスのサブクラスであり、画面上のポイント(指し示す位置)やインジケーター(表示標識)として定義されます。ユーザーがマウスを使ってシステムへの入力を選択・操作する際に、その位置を視覚的に示す重要な役割を担っています。GUIアプリケーションでは、状況に応じてカーソルの形状を変えることで、ユーザーに対して直感的なフィードバックを提供できます。例えば、処理中であることを伝える砂時計型のカーソルや、クリック可能な要素を示す手型のカーソルなどが代表的な例です。利用可能なカーソルの種類Cursorクラスには、あらかじめ定義されたさまざまなカ

  2. Windows 10でレジストリの変更がディスクに保存されるのはいつ?その理由も解説

    Windowsレジストリへの変更は、手動で行った場合でも、ソフトウェアやデバイスドライバーのインストール・アンインストール時に自動的に行われた場合でも、Windows 10やWindows Serverではすぐにディスクへ書き込まれるわけではありません。 レジストリの変更はいつ保存されるのか? レジストリへの更新内容は、即座にディスクへフラッシュ(書き込み)されることはありません。代わりに、最新のOSでは、変更されたレジストリデータが短い間隔で定期的にディスクへ書き込まれる仕組みになっています。 そのため、レジストリに変更を加えた直後に、停電などの予期せぬトラブルでコンピューターが強制終了し