web-dev-qa-db-ja.com

Java.lang.NoClassDefFoundErrorを解決する方法は?

両方の例をOracleの Java Tutorials で試してみました。どちらも正常にコンパイルされますが、実行時には、このエラーが発生します。

Exception in thread "main" Java.lang.NoClassDefFoundError: graphics/shapes/Square
    at Main.main(Main.Java:7)
Caused by: Java.lang.ClassNotFoundException: graphics.shapes.Square
    at Java.net.URLClassLoader$1.run(URLClassLoader.Java:366)
    at Java.net.URLClassLoader$1.run(URLClassLoader.Java:355)
    at Java.security.AccessController.doPrivileged(Native Method)
    at Java.net.URLClassLoader.findClass(URLClassLoader.Java:354)
    at Java.lang.ClassLoader.loadClass(ClassLoader.Java:424)
    at Sun.misc.Launcher$AppClassLoader.loadClass(Launcher.Java:308)
    at Java.lang.ClassLoader.loadClass(ClassLoader.Java:357)
    ... 1 more

Main.Javaファイルが間違ったフォルダにある可能性があります。これがディレクトリの階層です。

graphics
├ Main.Java
├ shapes
|   ├ Square.Java
|   ├ Triangle.Java
├ linepoint
|   ├ Line.Java
|   ├ Point.Java
├ spaceobjects
|   ├ Cube.Java
|   ├ RectPrism.Java

そしてこれがMain.Javaです。

import graphics.shapes.*;
import graphics.linepoint.*
import graphics.spaceobjects.*;

public class Main {
    public static void main(String args[]) {
        Square s = new Square(2,3,15);
        Line l = new Line(1,5,2,3);
        Cube c = new Cube(13,32,22);
    }
}

私はここで何をしていますか?

_ update _

Mainクラスをgraphicsパッケージに入れ(package graphics;をそれに追加し)、クラスパスを "_test"(グラフィックを含むフォルダ)に設定し、それをコンパイルし、(コマンドラインから)Java graphics.Mainを使用して実行しました。

本当に遅いUPDATE#2

私はEclipse(Notepad ++とJDKだけ)を使用していませんでした、そして上記のアップデートは私の問題を解決しました。しかし、これらの答えの多くはEclipseとIntelliJのためのものであるように見えますが、それらは似たような概念を持っています。

186
Jonathan Lam

コードをコンパイルした後は、プログラム内のクラスごとに.classファイルが作成されます。これらのバイナリファイルは、Javaがプログラムを実行するために解釈するバイトコードです。 NoClassDefFoundErrorは、クラスの動的ロードを担当するクラスローダー(この場合はJava.net.URLClassLoader)が、使用しようとしているクラスの.classファイルを見つけられないことを示します。

必要なクラスが存在しない場合はコードはコンパイルされません(リフレクションを使用してクラスがロードされない限り)。したがって、通常この例外はクラスパスに必要なクラスが含まれていないことを意味します。クラスローダー(具体的にはJava.net.URLClassLoader)は、クラスパスの各エントリで、フォルダーa/b/c /内のパッケージa.b.c内のクラスを探すことを忘れないでください。 NoClassDefFoundErrorは、コンパイルした.jarファイルの推移的な依存関係が欠けていて使用しようとしていることも示している可能性があります。

たとえば、クラスcom.example.Fooがある場合、コンパイル後にクラスファイルFoo.classができます。たとえば、作業ディレクトリが.../project/だとします。そのクラスファイルは.../project/com/exampleに配置しなければなりません、そしてあなたはあなたのクラスパスを.../project/にセットするでしょう。

サイドノート:JavaとJVMの言語に存在する素晴らしいツールを利用することをお勧めします。 EclipseやIDEAのような現代のIDE、そしてMavenやGradleのようなビルド管理ツールは、クラスパスを心配する必要がなく、コードに集中する必要がなくなります。とは言っても、 このリンク あなたがコマンドラインで実行するときにクラスパスを設定する方法を説明します。

192
Samuel

私はNoClassDefFoundErrorに関する他人の見方を修正したいと思います。

NoClassDefFoundErrorは、以下のような複数の理由で発生する可能性があります。

  1. ClassNotFoundException - コンパイル時に使用可能かどうかに関係なく、その参照クラスに対して.classが見つからない(つまり、基本クラスまたは子クラス)。
  2. クラスファイルは見つかりましたが、静的変数の初期化中に例外が発生しました
  3. クラスファイルが見つかりました。静的ブロックの初期化中に例外が発生しました

元の質問では、CLASSPATHを参照クラスのjarファイルまたはそのパッケージフォルダーに設定することで修正できる最初のケースでした。

「コンパイル時に利用可能」と言ってどういう意味ですか?

  • 参照クラスはコード内で使用されます。
    例:AとBの2つのクラス(Aを拡張)。 Bがコード内で直接参照されている場合は、コンパイル時に使用可能です。つまり、A a = new B();

「コンパイル時には利用できない」と言ってどういう意味ですか?

  • コンパイル時クラスと実行時クラスは異なります。たとえば、基本クラスは子クラスのクラス名を使用してロードされます。たとえばClass.forName( "classname")
    例:AとBの2つのクラス(Aを拡張)。コードは
    A。= Class.forName( "B")。newInstance();
115
p1nkrock

NoClassDefFoundErrorは、クラスがCompile timeのクラスパスに存在しますが、Runtimeのクラスパスには存在しないことを意味します。

Eclipseを使用している場合は、.classpathファイルのエントリとしてshapeslinepoints、およびspaceobjectsがあることを確認してください。

12

コンパイルおよび実行中にこれらのエラーのいずれかが発生した場合

* NoClassDefFoundError

* Error: Could not find or load main class hello

* Exception in thread "main" Java.lang.NoClassDefFoundError:javaTest/test/hello 
(wrong name: test/hello)
        at Java.lang.ClassLoader.defineClass1(Native Method)
        at Java.lang.ClassLoader.defineClass(Unknown Source)
        at Java.security.SecureClassLoader.defineClass(Unknown Source)
        at Java.net.URLClassLoader.defineClass(Unknown Source)
        at Java.net.URLClassLoader.access$100(Unknown Source)
        at Java.net.URLClassLoader$1.run(Unknown Source)
        at Java.net.URLClassLoader$1.run(Unknown Source)
        at Java.security.AccessController.doPrivileged(Native Method)
        at Java.net.URLClassLoader.findClass(Unknown Source)
        at Java.lang.ClassLoader.loadClass(Unknown Source)
        at Sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at Java.lang.ClassLoader.loadClass(Unknown Source)
        at Sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)

-------------------------- _ solutiion _ ----------- ------------

問題の大部分はパッケージ構成にあります。ソースコードのパッケージ分類に関して、クラスをフォルダに適切に配置する必要があります。

On Compiling process use this command:

javac -d . [FileName.Java]

To Run the class please use this command:

Java [Package].[ClassName]
10
sami
Java.lang.NoClassDefFoundError

compiletimeで何かが見つかったが、runtimeでは見つからなかったことを示します。たぶん、クラスパスに追加するだけです。

8
sschrass

クラス定義例外がない 目的のクラスがクラスパスに見つからない場合に発生します。コンパイル時クラス:クラスはJavaコンパイラから生成されましたが、実行時にどういうわけか従属クラスが見つかりません。

簡単な例を一つ見ていきましょう。

public class ClassA{
public static void main(String args[]){
     //Some gibberish Code...
     String text = ClassB.getString();
     System.out.println("Text is :" + text);
}

}

public class ClassB{
    public static String getString(){
      return "Testing Some Exception";
 }
}

今度は、上記の2つのJavaソースコードが何らかのフォルダに置かれていると仮定しましょう "NoClassDefinationFoundExceptionDemo"としましょう。

今すぐシェルを開きます(Javaが既に正しく設定されていると仮定します)

  1. フォルダ "NoClassDefinationFoundExceptionDemo"に移動します
  2. Javaソースファイルのコンパイルjavac ClassB javac ClassA
  3. 両方のファイルが正常にコンパイルされ、ClassA.classおよびClassB.classと同じフォルダにClassファイルが生成されます。
  4. 現在はClassPathを現在の作業ディレクトリに上書きしているので、次のコマンド Java -cpを実行します。 ClassA そしてそれはうまくいき、画面に出力が表示されます。
  5. 今、言うことができます、あなたは現在のディレクトリからClassB.classファイルを削除しました。そして今、あなたは再びコマンドを実行します。 Java -cp。 ClassA これで、NoClassDefFoundExceptionが返されます。 ClassAの依存関係であるClassBがクラスパス(つまり現在の作業ディレクトリ)に見つかりません。
6
bharatj

JavaのNoClassDefFoundError:

定義:

NoClassDefFoundErrorは、コンパイル時にクラスが存在し、実行時にJavaクラスパスで利用できなかった場合に発生します。通常、NoClassDefFoundErrorが発生すると、ログの以下の行に表示されます。スレッド "main"の例外Java.lang.NoClassDefFoundError

考えられる原因:

  1. このクラスはJavaクラスパスでは利用できません。

  2. Jarコマンドを使用してプログラムを実行している可能性があり、クラスがマニフェストファイルのClassPath属性で定義されていません。

  3. 起動スクリプトがClasspath環境変数をオーバーライドしています。

  4. NoClassDefFoundErrorはJava.lang.LinkageErrorのサブクラスなので、ネイティブライブラリのような依存関係が利用できない場合もあります。

  5. ログファイルでJava.lang.ExceptionInInitializerErrorを確認してください。静的初期化の失敗によるNoClassDefFoundErrorは非常に一般的です。

  6. J2EE環境で作業している場合、複数のClassloaderの中でClassが可視でもJava.lang.NoClassDefFoundErrorが発生する可能性があります。詳細については、例とシナリオのセクションを参照してください。

考えられる解決策:

  1. 必要なすべてのJavaクラスがアプリケーションのクラスパスに含まれていることを確認してください。最も一般的な間違いは、いくつかの外部ライブラリに依存しているJavaアプリケーションの実行を開始する前に、必要なクラスすべてを含めないことです。

  2. アプリケーションのクラスパスは正しいですが、Classpath環境変数はアプリケーションの実行前にオーバーライドされます。

  3. 前述のExceptionInInitializerErrorがアプリケーションのスタックトレースに表示されていないことを確認します。

リソース:

Java J2EEでJava.lang.NoClassDefFoundErrorを解決する3つの方法

Java.lang.NoClassDefFoundError - No Class Def Foundエラーを解決する方法

2
Virtual

プロジェクトがcom.blahcodeのようなパッケージ内にあり、クラスがMainと呼ばれる場合、コンパイル済みファイルは./out/com/blahcode/Main.classのようなディレクトリ構造に出力されるかもしれません。これはIntelliJ IDEAに特に当てはまります。

Shellまたはcmdから実行しようとするときは、cdをサブディレクトリとして含むcomにする必要があります。

cd out
Java -classpath . com.blahcode.Main
2
Hypershadsy

何ヶ月もの間NetBeansプロジェクトで作業した後、私は突然「低メモリ」アラートを受け取った直後にNoClassDefFoundErrorメッセージを受け取りました。クリーン再構築を行っても役に立ちませんでしたが、NetBeansをすべて閉じてプロジェクトを再開してもエラー報告はありませんでした。

1
Ed S

私のプロジェクトでは、問題を解決したのはChromeブラウザとchromedriverが互換性がないということでした。私はブラウザを開くことさえできない非常に古いバージョンのドライバを持っていました。両方の最新版をダウンロードしたところ、問題は解決しました。どうやってこの問題を発見しましたか?私は自分のプロジェクトにSeleniumネイティブのFirefoxドライバを使って、私のアプリケーションに組み込まれた古いバージョンのFFを使ってプロジェクトを実行したので、問題はブラウザとドライバの間の非互換性であることに気づきました。

これが私と同じような問題を抱えている人が、これと同じエラーメッセージを出してくれることを願っています。

1
Kyon Perez

私は今日問題に直面しています。私はAndroidプロジェクトを持っています、そしてmultidexを有効にした後、プロジェクトはもう開始しないでしょう。

その理由は、私はApplication classに追加されるべき他のすべての前に呼び出されるべきである特定のmultidexメソッドを呼び出すことを忘れていたということでした。

 MultiDex.install(this);

マルチチュートリアルを正しく有効にするには、このチュートリアルに従ってください。 https://developer.Android.com/studio/build/multidex.html

これらの行をApplicationクラスに追加してください。

 @Override
  protected void attachBaseContext(Context base) {
     super.attachBaseContext(base);
     MultiDex.install(this);
  }
1
CROSP

この回答は、 service で発生するJava.lang.NoClassDefFoundErrorに固有のものです。

私のチームは最近、サービスを提供するrpmをアップグレードした後にこのエラーを見ました。 rpmとその中のソフトウェアはMavenで構築されていたので、rpmには含まれていなかったコンパイル時の依存関係があったようです。

ただし、調べてみると、見つからなかったクラスは、スタックトレース内のいくつかのクラスと同じモジュール内にありました。さらに、これは最近ビルドに追加されたばかりのモジュールではありませんでした。これらの事実は、それがMavenの依存関係の問題ではないかもしれないことを示していました。

最終的な解決策: サービスを再起動してください。

Rpmのアップグレードによって、基盤となるjarファイルに対するサービスのファイルハンドルが無効になったようです。次に、サービスは、メモリにロードされていないクラスを見て、そのjarファイルハンドルのリストからそのクラスを検索しましたが、クラスのロード元のファイルハンドルが無効になっていたため、見つけられませんでした。サービスを再起動すると、すべてのファイルハンドルが強制的に再ロードされたため、rpmアップグレードの直後にメモリ内に見つからなかったクラスをロードできました。

その特定のケースが誰かに役立つことを願っています。

1
John Chesshir

このチェーンの中で私の2セント:

classpath full のパス(/home/user/lib/some_lib.jarではなく~/lib/some_lib.jar)が含まれていることを確認してください。そうしないと、NoClassDefFoundErrorエラーが発生する可能性があります。

0
khkarens

私は、Androidスタジオを使った私のAndroid開発に関しても同じ問題を抱えていました。提供されている解決策は一般的なもので、私には役立ちませんでした(少なくとも私にとっては)。何時間にも及ぶ調査の結果、私は次のような解決策を見つけました。Androidスタジオを使用して開発を行っているAndroid開発者に役立つかもしれません。設定 - >ビルド、実行、デプロイ - >インスタントラン - >最初のオプションのチェックを外してください。

この変更で私は立ち上がって走っています。これが私の開発者の友達に役立つことを願っています。

0
mask

Eclipse用に FileSyncプラグインを使用します Tomcatでライブデバッグができるので、EclipseワークスペースのNoClassFoundErrorディレクトリの同期エントリ=> classesをTomcatのbinに追加しましたが、metadataを受け取りました。 Eclipseのextlibディレクトリのフォルダ同期=>

C:\Users\Stuart\Eclipse-workspace\.metadata\.plugins\org.Eclipse.wst.server.core\tmp0\webapps\myApp\WEB-INF\lib

0
Stuart Cardall

あなたが最近このようなAndroidスタジオでマルチデックスサポートを追加したならば:

// To Support MultiDex
implementation 'com.Android.support:multidex:1.0.1'

だからあなたの解決策は単にアプリケーションの代わりにMultiDexApplicationから拡張されています

public class MyApp extends MultiDexApplication {
0
do01

Android Studioで私に起こりました。

私のために働いた解決策:ただスタジオを再起動してください。

0
yanish

クラスに静的ハンドラがあるかどうかを確認してください。もしそうなら、注意してください、ルーパーを持つスレッドでのみ静的ハンドラが開始される可能性があるので、クラッシュはこのように引き起こされる可能性があります。

1.最初に、単純なスレッドでclassのインスタンスを作成してクラッシュをキャッチします。

2.メインスレッドでClassのフィールドメソッドを呼び出すと、NoClassDefFoundErrorが返されます。

これがテストコードです。

public class MyClass{
       private static  Handler mHandler = new Handler();
       public static int num = 0;
}

mainアクティビティのonCreteメソッドにテストコード部分を追加します。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //test code start
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                MyClass myClass = new MyClass();
            } catch (Throwable e) {
                e.printStackTrace();
            }
        }
    }).start();

    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    MyClass.num = 3;
    // end of test code
}

initハンドラにhandlerThreadを使用してそれを修正する簡単な方法があります。

private static Handler mHandler;
private static HandlerThread handlerThread = new HandlerThread("newthread");
static {
    handlerThread.start();
    mHandler = new Handler(handlerThread.getLooper(), mHandlerCB);
}
0
Michael

もしあなたが複数のモジュールを使っているのなら、

dexOptions {
    preDexLibraries = false
}

ビルドファイルに。

0
Matin Petrulak

私は RCP(Rich Client Platform) としても知られるEclipseベースのアプリケーションを開発しています。そして私はリファクタリング(plugInから新しいものへの1つのクラスの移動)の後にこの問題に直面しています。

プロジェクトを掃除してMavenを更新しても意味がありません。

問題は Bundle-Activator によって引き起こされていました - /は自動的に更新されていません。新しいPlugInの MANIFEST.MF の下にあるBundle-Activatorを手動で更新したところ、問題が解決しました。

0

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

'Java -javaagent:tracer.jar [あなたのJava ARGS]'でプログラムを実行してください。

ロードされたクラスとそのクラスをロードしたローダーenvを示す出力を生成します。なぜクラスが解決できないのかをトレースするのはとても役に立ちます。

// 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;
            }
        });
    }
}
0
codeDr

この例外のエラーの原因の1つは、Proguardの定義の矛盾から生じる可能性があります。行方不明

-libraryJars "path.to.a.missing.jar.library"。

これは、jarがあるのに、clean&buildが失敗したのに、コンパイルと実行がうまく機能する理由を説明しています。 proguardセットアップで新しく追加されたjarライブラリを定義することを忘れないでください!

Proguardからのエラーメッセージは、jarがまったく存在しないときに到着する同様のantメッセージと混同されやすいため、実際には標準的なものではありません。一番下の部分にのみ、問題を起こしているという小さなヒントがあります。したがって、従来のクラスパスエラーなどの検索を開始するのは非常に論理的ですが、これは無駄になります。

明らかに、NoClassDefFound例外は実行時の結果になります。結果として得られる実行可能jarは、proguardの一貫性の欠如に基づいて構築されています。それを「地獄」と称している人もいます

0
carl

私のgenymotionデバイスではよく起こります。 Genymotionがインストールされているドライブに十分な量のメモリがあることを確認してください。

0
totteire