1. ホーム
  2. Java

java.lang.NoClassDefFoundError: Could not initialize class xxx 原因と対処法

2022-02-28 02:13:01
<パス

NoClassDefFoundErrorが発生する理由はいくつかありますが、ここでは静的変数や静的ブロックが原因であることが記されています。具体的にどのような例外が投げられるかというと、以下のような感じです。
java.lang.NoClassDefFoundError: クラス xxx を初期化できませんでした。

JVMがクラスをロードするとき、クラス内のスタティック変数を初期化するか、スタティックブロックを実行します。この時に例外が発生すると、クラスのロードに失敗し、その後、次の例のように、そのクラスを今後使用すると、NoClassDefFoundError例外がスローされます。

public class TestNoClassDefFoundError {
    public static void main(String[] args) throws InterruptedException {
        TestNoClassDefFoundError sample = new TestNoClassDefFoundError();
        sample.getClassWithInitErrors();
    }

    private void getClassWithInitErrors() throws InterruptedException {
        System.out.println("first new");
        Thread.sleep(500);
        try {
            // first new ClassWithInitErrors class, the JVM will load the class, initialize the static variables of the class or execute a static block
            new ClassWithInitErrors();
        } catch (Throwable t) {
            // Failed to load the class because the initialization of static variables failed.
            t.printStackTrace();
        }

        Thread.sleep(500);
        System.out.println("-----------------------------------------------------");
        System.out.println("second new");
        Thread.sleep(500);
        try {
            // the second new ClassWithInitErrors class, the JVM will not load the class, but throw a NoClassDefFoundError exception
            new ClassWithInitErrors();
        } catch (Throwable t) {
            t.printStackTrace();
        }
        Thread.sleep(500);
        System.out.println("-----------------------------------------------------");
        System.out.println("third new");
        Thread.sleep(500);
        try {
            // the third time new ClassWithInitErrors class, the JVM will not load the class, but throw NoClassDefFoundError exception
            new ClassWithInitErrors();
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }
}

classWithInitErrors {
    static int data = 1 / 0;
}

実装結果は以下のようになります。

The first new
java.lang.ExceptionInInitializerError
    at TestNoClassDefFoundError.getClassWithInitErrors(TestNoClassDefFoundError.java:12)
    at TestNoClassDefFoundError.main(TestNoClassDefFoundError.java:4)
Caused by: java.lang.ArithmeticException: / by zero
    at ClassWithInitErrors.
(TestNoClassDefFoundError.java:42)

    ... 2 more
-----------------------------------------------------
Second new
java.lang.NoClassDefFoundError: Could not initialize class ClassWithInitErrors
    at TestNoClassDefFoundError.getClassWithInitErrors(TestNoClassDefFoundError.java:24)
    at TestNoClassDefFoundError.main(TestNoClassDefFoundError.java:4)
-----------------------------------------------------
Third new
java.lang.NoClassDefFoundError: Could not initialize class ClassWithInitErrors
    at TestNoClassDefFoundError.getClassWithInitErrors(TestNoClassDefFoundError.java:34)
    at TestNoClassDefFoundError.main(TestNoClassDefFoundError.java:4)

上記のコードは、2番目以降のClassWithInitErrorsクラスへの使用は、NoClassDefFoundErrorエラーをスローするだけで、通常、我々はログを見るとき、我々は最初に最新のログを見るので、それはクラスの読み込みに失敗した本当の理由を見つけるのは簡単ではありません、この場合のために、我々はクラスの読み込みが初めてだったときのログを見つけて、java. lang.ExceptionInitializerError エラーで検索して失敗の原因を確認する必要があります。