java.lang.NoClassDefFoundError:クラスXXXを初期化できませんでした


165
public class PropHolder {
  public static Properties prop;

  static {
    //code for loading properties from file
  }
}

// Referencing the class somewhere else:
Properties prop = PropHolder.prop;

class PropHolder私のクラスです。クラスは、メインクラスと同じJARファイルにあります。そのため、JARがクラスパスから欠落しているので、それはすべきではありません。

でJARファイルを調べると、そこにリストされているjar tf myjarfileことがわかりPropHolder.classます。

ところで、コードは私のローカルマシンで正常に実行されています。しかし、いくつかのスクリプトを使用してLinuxサーバーに展開すると機能しませんでした。だから、コードの問題ではないと思います。しかし、何らかの理由で。展開プロセスの追跡は非常に困難です。

何が問題でしょうか?


jarの適切なディレクトリ構造はクラスパッケージと一致していますか?
ジョンB

いくつかのソースを見る必要があります。多くのことがこれを引き起こす可能性があります。たとえば、 'package'ステートメントですが、ファイルは実際には対応するパスにありません
jcomeau_ictx

3
1つの原因は、初期化中の例外です-他にエラー出力はありますか?
Michael Brewer-Davis、

回答:


210

私の最善の策は、ここに問題があることです:

static {
    //code for loading properties from file
}

キャッチされなかった例外が発生し、クラスをロードしようとする実際のClassLoaderまで伝搬されたように見えます。ただし、これを確認するにはスタックトレースが必要です。

それか、PropHolder.prop静的変数の作成時に発生しました。


私は何度も同じ問題に直面しています。static問題のせいだと思います。問題を解決するために何をする必要がありますか?
viper

1
staticブロックからスローされている例外を特定する必要があります。デバッグするにtry/catch(Exception e)は、ブロック全体を囲み、例外をログに記録します。その例外を修正する必要があります。通常、例外はログに記録されますが、非常に早い段階で発生する可能性があるクラスローディング中にログに記録されているため、見つけるのが難しい場合があります
John Vint

はい、私はコードをtry catchブロックし続けました、そしてそれは言いましたFailed to initialize ClassA。それが問題だと思いますJVM。システムを再起動したところ、すべて正常に動作しました。システムを再起動せずに将来この問題を解決し、簡単な解決策で問題を解決するにはどうすればよいですか。
viper

ClassAの初期化に失敗したのは、何か別の副作用です。cause利用できる場合は、を確認する必要があります。A NoClassDefFoundErrorは常に別のエラーに関連付けられているため、ログでそれを探すか、より適切にログを記録する必要があります(ファイルシステムの新しいファイルに強制的にログを記録するなど)
John Vint

JavaがエラーCouldNotInitializeStaticPartOfClassErrorなどをスローすると、より簡単に追跡できるようになります。そうすれば、開発者はどこを見ればよいかわかるでしょう。
Maarten

126

あなたはjava.lang.NoClassDefFoundErrorあなたのクラスが欠落していることを意味しない(その場合あなたはを得るでしょう)を取得していjava.lang.ClassNotFoundExceptionます。クラスを読み込もうとしたときに、クラスローダーがクラス定義の読み込み中にエラーが発生しました。

静的イニシャライザ内にtry / catchを配置して、例外を確認します。ここでいくつかのファイルを読み取り、それがローカル環境と異なる場合は、それが問題の原因である可能性が高いです(ファイルが見つからない、権限がないなど)。


1
1つの明確化は、NoClassDefFoundErrorがClassNotFoundExceptionを暗示していなくても、それでもNoClassDefFoundErrorの考えられる原因であることです。
ジョンヴィント2011

1
もしあなたがClassNotFoundExceptionを持っていたら、ClassLoaderはクラスをロードしようとするでしょうか、できないでしょうか?
jeha

4
クラスは、見つからなかった別のクラスをロードしている可能性があります。そのインスタンスの原因は依然としてClassNotFoundException
John Vint

1
明確にすべきだったのですが、これは例外を意味するだけです
。getCause

1
JAR(報告されたクラスが属している)が含まれていることを確認するのに約20分費やしたので、これは本当に役に立ちました。間違った方向を検討していることに気づいたら、一部の注釈クラスが欠落している可能性が高いことを簡単に理解し、報告されたものをとして宣言した@Statelessので、対応する依存関係を追加するだけで、先に進むことができました。先端をありがとう!
RAM237

33

NoClassDefFoundErrorは、静的ブロック内で何が問題になったかについての手がかりをあまり与えません。静的な{...}初期化コード内には、常に次のようなブロックを置くことをお勧めします。

static {
  try {

    ... your init code here

  } catch (Throwable t) {
    LOG.error("Failure during static initialization", t);
    throw t;
  }
}

コトリンでこれを行う方法?
Marlon、

ヒントを与えてくれてありがとう。私の場合、静的回線の初期化でNPEを取得していました。
アビシェク

3

同じ例外がありました、これが私が問題を解決した方法です:

前提条件:

  1. JUnitクラス(およびテスト)。これは別のクラスを拡張したものです。

  2. Springを使用して初期化されたApplicationContextは、プロジェクトを初期化します。

  3. アプリケーションコンテキストは@Beforeメソッドで初期化されました

解決:

親クラスはアプリケーションコンテキスト内から初期化されたいくつかのクラスも必要としたため、@ BeforeClassメソッドからアプリケーションコンテキストを初期化します。

これがお役に立てば幸いです。


2

上述したように、これにはいくつかのことが考えられます。私の場合、静的に初期化された変数がありました。これは、プロパティファイルのエントリの欠落に依存していました。不足しているエントリをプロパティファイルに追加し、問題は解決しました。


1

ほんの数日前、私はあなたと同じように同じ質問に会いました。すべてのコードは私のローカルマシンで正常に実行されますが、エラー(noclassdeffound&initialize)になります。だから私は自分の解決策を投稿しますが、理由はわかりません。単に可能性を前進させるだけです。誰かがこれを説明してくれることを願っています。@ John Vintまず、私の問題を紹介します。私のコードには、静的変数と静的ブロックの両方があります。この問題に初めて遭遇したとき、私はJohn Vintの解決策を試し、例外をキャッチしようとしました。しかし、私は何も捕まえませんでした。だから私はそれが静的変数(しかし今ではそれらが同じものであることを知っている)がまだ何も見つからなかったためだと思った。それで、私はLinuxマシンと私のコンピューターの違いを見つけようとします。次に、この問題が発生するのは、1つのプロセスで複数のスレッドが実行されている場合のみです(ちなみに、Linuxマシンには2つのコアと2つのプロセスがあります)。つまり、同じプロセスで実行される2つのタスク(両方とも静的ブロックまたは変数を含むコードを使用)がある場合、それは失敗しますが、異なるプロセスで実行される場合、両方とも問題ありません。Linuxマシンでは、

mvn -U clean  test -Dtest=path 

タスクを実行すると、静的変数はコンテナーを開始するため(または、新しいクラスローダーを初期化する可能性があるため)、jvmが停止するまでとどまり、jvmは1つのプロセス内のすべてのタスクが停止したときにのみ停止します。すべてのタスクが新しいコンテナー(またはクラスローダー)を開始し、jvmを混乱させます。その結果、エラーが発生します。それを解決するにはどうすればよいですか?私の解決策は、mavenコマンドに新しいコマンドを追加し、すべてのタスクを同じコンテナーに移動させることです。

-Dxxx.version=xxxxx #sorry can't post more

たぶん、あなたはすでにこの問題を解決しているかもしれませんが、それでも同じ問題に遭遇する他の人に役立つことを願っています。


さらに、コードがLinuxマシンで実行されると、上記のエラーに従い、別の問題が発生しますjava.lang.ExceptionInInitializerError: null。つまり、クラスローダーでクラスが見つからないか、どれをロードするかわからないということです(おそらく)。会いましたか?
MonkeyKing、2015年

1

同じ例外がありましたが、デバッグモードで実行しているときにのみ、これが問題を解決した方法です(3日後)。build.gradleで、defaultConfigセクションに「multiDexEnabled true」を設定しました。

        defaultConfig {
    applicationId "com.xxx.yyy"
    minSdkVersion 15
    targetSdkVersion 28
    versionCode 5123
    versionName "5123"
    // Enabling multidex support.
    multiDexEnabled true
}

どうやらこれで十分ではなかったようです。しかし、私が変更したとき:

public class MyAppClass  extends Application 

に:

public class MyAppClass  extends MultiDexApplication 

これで解決しました。これが誰かを助けることを願っています


0

Androidプロジェクトで作業している場合は、Androidクラスで静的メソッドを呼び出さないようにしてください。私はJUnit + Mockitoのみを使用しているので、おそらく他のいくつかのフレームワークが問題を完全に回避するのに役立つかもしれませんが、わかりません。

私の問題はUri.parse(uriString)、単体テストの静的初期化子の一部として呼び出すことでした。UriクラスはAndroid APIであるため、単体テストビルドはそれを見つけることができませんでした。この値をnull代わりに変更すると、すべてが正常に戻りました。


0

同じ問題が発生しました:java.lang.NoClassDefFoundError:クラスcom.xxx.HttpUtilsを初期化できませんでした

static {
    //code for loading properties from file
}

これは環境問題です。つまり、application.ymlのプロパティが正しくないか空です。


0

同じ問題が発生します。以下のような静的ブロックでBeanオブジェクトを初期化しました。

static {
    try{
        mqttConfiguration = SpringBootBeanUtils.<MqttConfiguration>getBean(MqttConfiguration.class);
    }catch (Throwable e){
        System.out.println(e);
    }
 }

私のbean obejct initionのプロセスがNPEを引き起こしたという理由だけで、私はそれにトラブルを起こします。静的コードブロックを注意深くチェックする必要があると思います。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.