JavaでNoClassDefFoundErrorが発生するのはなぜですか?


530

私は得ています NoClassDefFoundError、私は私のJavaアプリケーションを実行したとき。通常、これの原因は何ですか?


1
Javaプログラムを正しい構文で実行しなかった場合にも発生する可能性があります。たとえば、完全なパッケージ名(my.package.myClass)を使用して、ルートbinフォルダーからクラスを呼び出す必要があります。できればもっと具体的にしますが、私はあまりJavaの人ではありません。私はこれを数回台無しにしたことを覚えています。
フランクハダー2008

17
@BoltClock多数の重複を指摘するには、標準的な質問が必要です。なぜこれができないのですか?
Raedwald、2014年

21
コミュニティがより価値があると思う答えがトップになるように、受け入れられた答えを変更することを検討しましたか?
Martin Smith、

回答:


264

これは、コードが依存するクラスファイルがあり、コンパイル時に存在するが実行時に見つからない場合に発生します。ビルド時間とランタイムクラスパスの違いを探します。


1
ソースファイルを間違った名前空間/パッケージの下に置くと、このエラーが発生しました。私はそれをどこにでも置くことができると考えました、そしてコンパイラーは幸せでした。ランタイムが幸せになるためにも、私はもっと勤勉でなければならなかったことがわかります。
CenterOrbit 2014年

1
ファイルのアップロード中にサーバーのメモリが不足すると、このエラーが一度発生しました。アップロードを試みるたびに、異なるエラーが発生しました。最終的に、ヒープ領域が足りないことがわかりました。
James M. Lay

81
この答えは必ずしも正しいとは限らず、多くの人々に誤解を与えるでしょう!以下のJaredからのより良い答えを参照してください。
Dave L.

4
@DaveL。ありがとう!400以上の賛成票でのJaredの回答は、以下のとおりです。-4の賛成(反対?)投票での1つの回答は、それよりはるかに上です。SOの回答の順序付けロジックには、怪しげなものがあります。
Saurabh Patil 2017

1
これは誰かのためのロングショットですが、問題のクラスに無効な文字で初期化されたSimpleDateFormatが含まれていたため、このエラーが発生しました( 'T'の代わりに中央にTがありました)。
ライアンD

818

これはコンパイル時と実行時のクラスパスの不一致が原因である可能性がありますが、必ずしもそうではありません。

この場合、2つまたは3つの異なる例外を頭の中でまっすぐに保つことが重要です。

  1. java.lang.ClassNotFoundException この例外は、クラスがクラスパスで見つからなかったことを示します。これは、クラス定義をロードしようとしていて、クラスパスにクラスが存在しなかったことを示しています。

  2. java.lang.NoClassDefFoundError この例外は、JVMがそのクラス定義の内部クラス定義データ構造を調べ、それが見つからなかったことを示しています。これは、クラスパスからロードできなかったということとは異なります。通常、これは以前にクラスパスからクラスをロードしようとしたが、なんらかの理由で失敗したことを示します。今度はクラスを再度使用しようとしています(したがって、前回失敗したため、クラスをロードする必要があります)が、先にロードに失敗したため(そして再び失敗するのではないかと疑われているため)、ロードしようとはしません。以前の失敗は、ClassNotFoundExceptionまたはExceptionInInitializerError(静的な初期化ブロックの失敗を示す)またはその他の問題である可能性があります。ポイントは、NoClassDefFoundErrorは必ずしもクラスパスの問題ではないということです。


30
NoClassDefFoundErrorの原因について言及してくれてありがとう、これは私に大いに役立ちました!私の場合、以前にExceptionInInitializerErrorがスローされていましたが、これが静的ブロックのエラーを見つける方法です。
トーマス

@Jared、私がを取得するとError: Could not find or load main class、それはエラーのどのカテゴリに分類されますか?
Vikram 2013

@Pops:動詞 "try"のオブジェクトを指定するために言語をより冗長にしました:)
Jared

1
@Vikram「メインクラスを検出またはロードできませんでした」はJavaの例外ではなく、ランチャー(JARおよびメインマニフェスト属性を検査する)が原因です。
1

2
ClassNotFoundExceptionは、クラスにエラーまたは例外をスローする静的な初期化がある場合にもスローされます。彼らはおそらくそのイベントに別の名前を選んだはずです。
coladict

125

これが説明するコードjava.lang.NoClassDefFoundErrorです。詳細については、Jaredの回答を参照してください。

NoClassDefFoundErrorDemo.java

public class NoClassDefFoundErrorDemo {
    public static void main(String[] args) {
        try {
            // The following line would throw ExceptionInInitializerError
            SimpleCalculator calculator1 = new SimpleCalculator();
        } catch (Throwable t) {
            System.out.println(t);
        }
        // The following line would cause NoClassDefFoundError
        SimpleCalculator calculator2 = new SimpleCalculator();
    }

}

SimpleCalculator.java

public class SimpleCalculator {
    static int undefined = 1 / 0;
}

3
そしてその理由は、最初に試した後、jvmは動作しないことをすでに知っており、2回目に異なる例外をスローするためです。
イカメン

@ikamenどうやらSimpleCalculatorゼロ除算後の失敗したクラス初期化がどこかに保存されているようです?誰かがこの動作の公式ドキュメントを参照していますか?
ᴠɪɴᴄᴇɴᴛ

4
@PhilipRego「純粋な」NoClassDefFoundErrorの意味がわからない。初めてnew SimpleCalculator()呼び出されたときに、ArithmeticExceptionの原因によるExceptionInInitializerErrorが発生します。2回目に呼び出すnew SimpleCalculator()と、他と同じくらい純粋なNoClassDefFoundErrorが返されます。ポイントは、SimpleCalculator.classが実行時にクラスパス上にないこと以外の理由でNoClassDefFoundErrorを取得できることです。
harperska

36

JavaのNoClassDefFoundError

定義:

  1. Java仮想マシンは、コンパイル時に使用可能だった実行時に特定のクラスを見つけることができません。

  2. コンパイル時にクラスが存在したが、実行時にJavaクラスパスで使用できなかった場合。

ここに画像の説明を入力してください

例:

  1. クラスはクラスパスにありません、それを知るための確実なショット方法はありませんが、多くの場合、System.getproperty( "java.classpath")を印刷するための外観を持つことができ、そこからクラスパスを印刷します。実際のランタイムクラスパスのアイデア。
  2. NoClassDefFoundErrorの簡単な例は、クラスが欠落しているJARファイルに属しているか、JARがクラスパスに追加されていないか、私の同僚の1人がtibco.jarをtibco_v3.jarに変更してプログラムがjava.lang.NoClassDefFoundErrorで失敗し、何が問題なのかと思っていました。

  3. 機能すると思われるクラスパスを明示的に-classpathオプションで実行してみてください。それが機能している場合は、誰かがjavaクラスパスをオーバーライドしていることを示す簡単な兆候です。

  4. JARファイルでの権限の問題も、JavaでNoClassDefFoundErrorを引き起こす可能性があります。
  5. XML設定のタイプミスも、JavaでNoClassDefFoundErrorを引き起こす可能性があります。
  6. JAppletの場合のように、パッケージで定義されているコンパイル済みクラスがロード中に同じパッケージに存在しない場合、JavaでNoClassDefFoundErrorがスローされます。

可能な解決策:

  1. クラスはJavaクラスパスでは使用できません。
  2. J2EE環境で作業している場合、複数のClassloader間のClassの可視性がjava.lang.NoClassDefFoundErrorを引き起こす可能性がある場合、詳細な説明については、例とシナリオのセクションを参照してください。
  3. ログファイルでjava.lang.ExceptionInInitializerErrorを確認します。静的初期化の失敗によるNoClassDefFoundErrorは非常に一般的です。
  4. NoClassDefFoundErrorはjava.lang.LinkageErrorのサブクラスであるため、ネイティブライブラリなどの依存関係の1つが利用できない場合にも発生する可能性があります。
  5. 起動スクリプトは、クラスパス環境変数を上書きしています。
  6. jarコマンドを使用してプログラムを実行している可能性がありますが、クラスがマニフェストファイルのClassPath属性で定義されていません。

リソース:

NoClassDefFoundErrorを解決する3つの方法

java.lang.NoClassDefFoundError問題パターン


1
すばらしい答えです。私はあなたが提案するすべてを試しましたが、それでもその問題があります。jarがSpringで動作しているため、これらの一部を除外できますが、java.sql(私の場合、Hanaのsap dbドライバー)には好まれないようです。
JE Carter II

実際にはSystem.getproperty( "java.class.path")と呼ばれます
RIJIK

33

実行時に見つかった互換性のないバージョンのクラスを使用してコードをコンパイルすると、NoClassDefFoundエラーが発生することがあります。私が思い出す具体的な例は、Apache軸ライブラリです。私のランタイムクラスパスには実際には2つのバージョンがあり、古いバージョンと互換性のないバージョンを取得していて、正しいバージョンではなかったため、NoClassDefFoundエラーが発生していました。これは、私がこれに似たコマンドを使用していたコマンドラインアプリにありました。

set classpath=%classpath%;axis.jar

私はそれを使用して適切なバージョンを取得することができました:

set classpath=axis.jar;%classpath%;

4
同じ問題があった。結局、Java 7でwarファイルをコンパイルしましたが、私のTomcatインストールはJava6を使用していました。私は環境変数を更新しなければなり
ませんでした

4
これがそのように発生した場合、Javaは混乱していると言えます。+2これが真の場合。まだ確認できません。trueが見つかった場合は、もう一度(コメントで)+1します
超新星

7

これは最高のソリューションです私がこれまでに見つけです。

org.mypackageクラスを含むと呼ばれるパッケージがあるとします:

  • HelloWorld(メインクラス)
  • SupportClass
  • UtilClass

このパッケージを定義するファイルは、ディレクトリD:\myprogram(Windowsの場合)または/home/user/myprogram(Linux)の。

ファイル構造は次のようになります。 ここに画像の説明を入力してください

Javaを呼び出すときに、実行するアプリケーションの名前を指定しますorg.mypackage.HelloWorld。ただし、パッケージを定義するファイルとディレクトリの場所をJavaに通知する必要もあります。したがって、プログラムを起動するには、次のコマンドを使用する必要があります。 ここに画像の説明を入力してください


6

MavenでSpring Frameworkを使用していて、このエラーをプロジェクトで解決しました。

クラスでランタイムエラーが発生しました。プロパティを整数として読み込んでいましたが、プロパティファイルから値を読み込んだとき、その値はdoubleでした。

Springは、ランタイムが失敗した行の完全なスタックトレースを提供しませんでした。それは単に言いましたNoClassDefFoundError。しかし、それをネイティブJavaアプリケーションとして実行したとき(MVCから取り出したとき)、ExceptionInInitializerErrorすると、どちらが本当の原因で、どちらがエラーを追跡したかがわかります。

@xliの回答から、コードのどこに問題があるのか​​がわかりました。


1
サーブレットをプログラミングしたときにも同じことが起こりました(NoClassDefFoundError実際にはが原因でExceptionInInitalizerError、これはが原因ですDateTimeParseException)。少し誤解を招きやすいですね。私は彼らがおそらくそのようにする理由を持っていることを知っていますが、それNoClassDefFoundErrorを推論する必要なしに、少なくとも別の例外の結果であった少なくとも小さなヒントがあればとても良いでしょう。ExceptionInInitializerErrorもう一度投げるだけの方がはるかにはっきりします。2つの間の接続がそれほど明白でない場合があります。
パルトロミエZieliński

5

ランタイムクラスローダーによって読み込まれたクラスが、Javaルートローダーによって既に読み込まれたクラスにアクセスできない場合、NoClassFoundErrorが発生します。異なるクラスローダーは異なるセキュリティドメインにあるため(Javaによると)、jvmでは、ルートローダーによって既にロードされているクラスをランタイムローダーのアドレス空間で解決できません。

「java -javaagent:tracer.jar [YOUR java ARGS]」を使用してプログラムを実行します

ロードされたクラスと、クラスをロードしたローダー環境を示す出力を生成します。クラスを解決できない理由を追跡することは非常に役立ちます。

// ClassLoaderTracer.java
// From: https://blogs.oracle.com/sundararajan/entry/tracing_class_loading_1_5

import java.lang.instrument.*;
import java.security.*;

// manifest.mf
// Premain-Class: ClassLoadTracer

// jar -cvfm tracer.jar manifest.mf ClassLoaderTracer.class

// java -javaagent:tracer.jar  [...]

public class ClassLoadTracer 
{
    public static void premain(String agentArgs, Instrumentation inst) 
    {
        final java.io.PrintStream out = System.out;
        inst.addTransformer(new ClassFileTransformer() {
            public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {

                String pd = (null == protectionDomain) ? "null" : protectionDomain.getCodeSource().toString();
                out.println(className + " loaded by " + loader + " at " + new java.util.Date() + " in " + pd);

                // dump stack trace of the thread loading class 
                Thread.dumpStack();

                // we just want the original .class bytes to be loaded!
                // we are not instrumenting it...
                return null;
            }
        });
    }
}

1
リンクが死んでいる。アーカイブされたバージョンをお試しください: web.archive.org/web/20131216000019/https://blogs.oracle.com/...は
avgvstvs

5

あなたが多く見るかもしれない1つの興味深いケースはあなたが以下のNoClassDefFoundErrors場合です:

  1. throwA RuntimeExceptionにおけるstaticクラスのブロックExample
  2. インターセプトする(またはテストケースでスローされるように問題ない場合))。
  3. このクラスのインスタンスを作成してみてください Example

static class Example {
    static {
        thisThrowsRuntimeException();
    }
}

static class OuterClazz {

    OuterClazz() {
        try {
            new Example();
        } catch (Throwable ignored) { //simulating catching RuntimeException from static block
            // DO NOT DO THIS IN PRODUCTION CODE, THIS IS JUST AN EXAMPLE in StackOverflow
        }

        new Example(); //this throws NoClassDefFoundError
    }
}

NoClassDefErrorExceptionInInitializerError静的ブロックから一緒にスローされますRuntimeException


これはNoClassDefFoundErrorsユニットテストに表示される場合に特に重要なケースです。

ある意味ではstatic、テスト間でブロックの実行を「共有」しますが、イニシャルExceptionInInitializerErrorは1つのテストケースに含まれます。問題のあるExampleクラスを使用する最初のもの。Exampleクラスを使用する他のテストケースは単にスローしNoClassDefFoundErrorsます。


4
これは、実際の生活でかなり役立つアドバイスです。クラス属性の初期化子で同じ状況が発生しました。ログで実際の問題を確認できるのは一度だけです。クラスがロードされた(または試みられた)場合は、すべてを再起動する必要があります。
DailyFrankPeter

4

以下のテクニックは私を何度も助けました:

System.out.println(TheNoDefFoundClass.class.getProtectionDomain().getCodeSource().getLocation());

TheNoDefFoundClassは、プログラムで使用されているのと同じライブラリの古いバージョンの設定が原因で「失われる」可能性があるクラスです。これは、クライアントソフトウェアが独自のクラスローダーと最も人気のあるlibの多数の古代バージョンで武装した主要なコンテナーに展開されている場合に最も頻繁に発生します。


3

コード(EMFなど)を生成した場合、すべてのスタック領域を消費する静的イニシャライザが多すぎる可能性があります。

Stack Overflowの質問を参照してください。Javaスタックサイズを増やす方法は?


「EMF」?あなたが意味するか、「MEFを
Peter Mortensen

2
いいえ。EclipseモデリングフレームワークとしてのEMf。自動車では、生成されたコードを実行すると、このエラーが発生する可能性があります。
Aykut Kllic

1

すべてのモジュールのpreDexLibrariesを無効にすることで問題を解決しました:

dexOptions {
        preDexLibraries false
        ...

1

NoClassDefFoundError静的イニシャライザがランタイムで利用できないリソースバンドルをロードしようとしたときにも発生する可能性があります。たとえば、影響を受けるクラスがMETA-INFディレクトリからロードしようとしたがそこにないプロパティファイルなどです。キャッチしNoClassDefFoundErrorないと、完全なスタックトレースを表示できないことがあります。これを克服するには、次のcatch句を一時的に使用できますThrowable

try {
    // Statement(s) that cause the affected class to be loaded
} catch (Throwable t) {
    Logger.getLogger("<logger-name>").info("Loading my class went wrong", t);
}

これは誤りです。不足しているリソースは、あなたにこのエラーを与えることはありません。クラスが欠落している場合にのみ取得します。
スティーブンC

@StephenCその部分をもっと強調すべきかもしれませんが、私は書きましたfor example a properties file that the affected class tries to load from the META-INF directory。これは実際に私に起こりNoClassDefFoundError、欠落しているプロパティファイルを追加することで解決できました。上記の状況下ではこのエラーを予期しないため、この回答を正確に追加しました。
ᴠɪɴᴄᴇɴᴛ

1
リソースファイル見つからないことがその例外をトリガーできる唯一の方法は、static初期化でリソースファイルをロードしようとした場合にのみ、説明で非常に重要な何かを見落としました。これにより、チェックされない例外がトリガーされ、クラスが初期化されました。失敗する。静的な初期化から伝播する未チェックの例外があればそれを行います。
スティーブンC

私が間違っている場合(つまり、static初期化の失敗が原因ではない場合)、動作を示す実際の例(MCVEなど)を参照してください。
スティーブンC

1
@StephenCあなたはまったく正しいです:(私はこの問題が発生したケースを調べましたが、実際にはリソースバンドルをロードしようとする静的イニシャライザが関係していました。原因の説明を追加/修正します。これを指摘していただきありがとうございますアウト。
ᴠɪɴᴄᴇɴᴛ

1

プロジェクトに別のモジュールのMaven依存関係を追加すると、このエラーが発生しました。問題は-Xss2m、プログラムのJVMオプションに追加することでようやく解決されました(JDK5.0以降、デフォルトでは1メガバイトです)。プログラムにはクラスをロードするのに十分なスタックがないと考えられています。


0

java.lang.NoClassDefFoundError: org/apache/log4j/Loggerエラーのために誰かがここに来た場合、私の場合は、log4j 2を使用して(ただし、付属のすべてのファイルを追加しなかったため)、log4j 1を使用した依存ライブラリがいくつかあったため、Log4jを追加しました。 1.xブリッジ:log4j-1.2-api-<version>.jarlog4jに付属するjar 2. log4j 2 移行の詳細。


0

同じプロジェクトの2つの異なるチェックアウトコピー

私の場合、問題はEclipseが同じプロジェクトの2つの異なるコピーを区別できないことでした。私は1つをトランク(SVNバージョン管理)でロックし、もう1つは一度に1つのブランチで作業しています。私はJUnitテストケースとして、作業コピーの1つの変更を試しました。これには、プライベート内部クラスをそれ自体でパブリッククラスとして抽出することが含まれ、それが機能している間に、プロジェクトのもう1つのコピーを開いて、他のいくつかを見回しました。変更が必要なコードの一部。ある時点で、NoClassDefFoundErrorプライベート内部クラスがそこにないという不満がポップアップしました。スタックトレースをダブルクリックすると、間違ったプロジェクトコピーのソースファイルが表示されました。

プロジェクトのトランクコピーを閉じてテストケースを再度実行すると、問題は解消されました。


0

このエラーは、Javaバージョンの要件がチェックされていないことが原因である可能性があります。

私の場合、SDKMANを使用してJava 9からJava 8に切り替えることで、注目度の高いオープンソースプロジェクトを構築しているときにこのエラーを解決できました

sdk list java
sdk install java 8u152-zulu
sdk use java 8u152-zulu

次に、以下の説明に従ってクリーンインストールを実行します。


ビルドツールとしてMavenを使用する場合、テストを無効にしてクリーンな「インストール」ビルドを行うと役立つことがあります。

mvn clean install -DskipTests

今すぐことすべてが構築され、インストールされている、あなたは先に行くと、テストを実行することができます。

mvn test

0

プロジェクトのJavaビルドパスの[順序とエクスポート]タブでクラスをエクスポートしないと、NoClassDefFoundエラーが発生しました。プロジェクトのビルドパスに追加する依存関係の[注文とエクスポート]タブに必ずチェックマークを付けてください。Eclipse警告を参照してください:XXXXXXXXXXX.jarはエクスポートまたは公開されません。実行時ClassNotFoundExceptionsが発生する可能性があります。


0

また、IDEから特定のパッケージ名でコードファイルをコピーし、ターミナルを使用して実行したい場合もあります。最初にコードからパッケージ名を削除する必要があります。これは私に起こります。


0

私の場合、JDKバージョンの不一致が原因でこのエラーが発生しました。Intelijからアプリケーションを実行しようとしても機能しませんでしたが、コマンドラインから実行すると機能しました。これは、IntelijがセットアップされたJava 11 JDKで実行しようとしたが、コマンドラインではJava 8 JDKで実行されていたためです。[ファイル]> [プロジェクト構造]> [プロジェクト設定]> [プロジェクトSDK]でその設定を切り替えた後、うまくいきました。


0

私の場合、エラーはこれらのトピックとはまったく関係がなく、非常に些細で簡単に解決できる理由がありました:コントローラーのエンドポイントに間違った注釈がありました( Spring Bootアプリケーション)。


0

Libertyサーバーで動作するJavaEEのNoClassDefFoundErrorで興味深い問題が発生しました。私はIMSリソースアダプタを使用していましたが、server.xmlにはすでにimsudbJXA.rar用のリソースアダプタがありました。imsudbXA.rarの新しいアダプタを追加すると、DLIException、IMSConnectionSpec、またはSQLInteractionSpecのインスタンスオブジェクトでこのエラーが発生し始めます。理由はわかりませんが、imsudbXA.rarのみを使用して作業用に新しいserver.xmlを作成することで解決しました。server.xmlで複数のリソースアダプターを使用することは問題ないと確信しています。


-1

Javaは実行時にクラスAを見つけることができませんでした。クラスAは、別のワークスペースのMavenプロジェクトArtClientにありました。そこで、ArtClientをEclipseプロジェクトにインポートしました。私のプロジェクトのうちの2つは、依存関係としてArtClientを使用していました。ライブラリ参照をこれらのプロジェクト参照(ビルドパス->ビルドパスの構成)に変更しました。

そして問題は消え去った。


-1

同じ問題があり、何時間もストックしていた。

私は解決策を見つけました。私の場合、そのために静的メソッドが定義されていました。JVMはそのクラスの別のオブジェクトを作成できません。

例えば、

private static HttpHost proxy = new HttpHost(proxyHost, Integer.valueOf(proxyPort), "http");

-6

SRCライブラリから2つのファイルを削除した後にこのメッセージが表示され、それらを元に戻したときに、このエラーメッセージが何度も表示されました。

私の解決策は、Eclipseを再起動することでした。それ以来、このメッセージはもう見ていません:-)


4
それは最も投票された回答で説明されています。最初にコンパイルしたとき、ファイルはそこにあり、その後いくつかのファイルを削除し、クラスは削除されたため、実行時にClassNotFoundを取得しましたが、それらを元に戻しましたが、それでもEclipseはしませんでした生成されたクラスがまだ見つからないことに注意してください。ただし、Eclipseを再起動した後、ワークスペースが更新され、クラスが再び使用可能になりましたが、これは通常、解決策または回避策ではありません。解決策は、ランタイムで欠落しているクラス/ jarを見つけています。クラスパス。
ホセマヌエルゴメスアルバレス

-7

中に必ずこのマッチを行いますmodule:appmodule:lib

android {
    compileSdkVersion 23
    buildToolsVersion '22.0.1'
    packagingOptions {
    }

    defaultConfig {
        minSdkVersion 17
        targetSdkVersion 23
        versionCode 11
        versionName "2.1"
    }

3
あなたのソリューションは、この一般的な問題にどのように関連していますか?
Taavi Ilves、2016年

サンプル構成はバランスが取れていません(3 {sと2 })。直せますか?
Peter Mortensen、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.