両方の例を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のためのものであるように見えますが、それらは似たような概念を持っています。
コードをコンパイルした後は、プログラム内のクラスごとに.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のようなビルド管理ツールは、クラスパスを心配する必要がなく、コードに集中する必要がなくなります。とは言っても、 このリンク あなたがコマンドラインで実行するときにクラスパスを設定する方法を説明します。
私はNoClassDefFoundError
に関する他人の見方を修正したいと思います。
NoClassDefFoundError
は、以下のような複数の理由で発生する可能性があります。
元の質問では、CLASSPATHを参照クラスのjarファイルまたはそのパッケージフォルダーに設定することで修正できる最初のケースでした。
「コンパイル時に利用可能」と言ってどういう意味ですか?
「コンパイル時には利用できない」と言ってどういう意味ですか?
NoClassDefFoundError
は、クラスがCompile time
のクラスパスに存在しますが、Runtime
のクラスパスには存在しないことを意味します。
Eclipseを使用している場合は、.classpath
ファイルのエントリとしてshapes
、linepoints
、およびspaceobjects
があることを確認してください。
コンパイルおよび実行中にこれらのエラーのいずれかが発生した場合
* 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]
Java.lang.NoClassDefFoundError
compiletimeで何かが見つかったが、runtimeでは見つからなかったことを示します。たぶん、クラスパスに追加するだけです。
クラス定義例外がない 目的のクラスがクラスパスに見つからない場合に発生します。コンパイル時クラス:クラスは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が既に正しく設定されていると仮定します)
JavaのNoClassDefFoundError:
定義:
NoClassDefFoundErrorは、コンパイル時にクラスが存在し、実行時にJavaクラスパスで利用できなかった場合に発生します。通常、NoClassDefFoundErrorが発生すると、ログの以下の行に表示されます。スレッド "main"の例外Java.lang.NoClassDefFoundError
考えられる原因:
このクラスはJavaクラスパスでは利用できません。
Jarコマンドを使用してプログラムを実行している可能性があり、クラスがマニフェストファイルのClassPath属性で定義されていません。
起動スクリプトがClasspath環境変数をオーバーライドしています。
NoClassDefFoundErrorはJava.lang.LinkageErrorのサブクラスなので、ネイティブライブラリのような依存関係が利用できない場合もあります。
ログファイルでJava.lang.ExceptionInInitializerErrorを確認してください。静的初期化の失敗によるNoClassDefFoundErrorは非常に一般的です。
J2EE環境で作業している場合、複数のClassloaderの中でClassが可視でもJava.lang.NoClassDefFoundErrorが発生する可能性があります。詳細については、例とシナリオのセクションを参照してください。
考えられる解決策:
必要なすべてのJavaクラスがアプリケーションのクラスパスに含まれていることを確認してください。最も一般的な間違いは、いくつかの外部ライブラリに依存しているJavaアプリケーションの実行を開始する前に、必要なクラスすべてを含めないことです。
アプリケーションのクラスパスは正しいですが、Classpath環境変数はアプリケーションの実行前にオーバーライドされます。
前述のExceptionInInitializerErrorがアプリケーションのスタックトレースに表示されていないことを確認します。
リソース:
Java J2EEでJava.lang.NoClassDefFoundErrorを解決する3つの方法
Java.lang.NoClassDefFoundError - No Class Def Foundエラーを解決する方法
プロジェクトがcom.blahcode
のようなパッケージ内にあり、クラスがMain
と呼ばれる場合、コンパイル済みファイルは./out/com/blahcode/Main.class
のようなディレクトリ構造に出力されるかもしれません。これはIntelliJ IDEAに特に当てはまります。
Shellまたはcmdから実行しようとするときは、cd
をサブディレクトリとして含むcom
にする必要があります。
cd out
Java -classpath . com.blahcode.Main
何ヶ月もの間NetBeansプロジェクトで作業した後、私は突然「低メモリ」アラートを受け取った直後にNoClassDefFoundErrorメッセージを受け取りました。クリーン再構築を行っても役に立ちませんでしたが、NetBeansをすべて閉じてプロジェクトを再開してもエラー報告はありませんでした。
私のプロジェクトでは、問題を解決したのはChromeブラウザとchromedriverが互換性がないということでした。私はブラウザを開くことさえできない非常に古いバージョンのドライバを持っていました。両方の最新版をダウンロードしたところ、問題は解決しました。どうやってこの問題を発見しましたか?私は自分のプロジェクトにSeleniumネイティブのFirefoxドライバを使って、私のアプリケーションに組み込まれた古いバージョンのFFを使ってプロジェクトを実行したので、問題はブラウザとドライバの間の非互換性であることに気づきました。
これが私と同じような問題を抱えている人が、これと同じエラーメッセージを出してくれることを願っています。
私は今日問題に直面しています。私は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);
}
この回答は、 service で発生するJava.lang.NoClassDefFoundErrorに固有のものです。
私のチームは最近、サービスを提供するrpmをアップグレードした後にこのエラーを見ました。 rpmとその中のソフトウェアはMavenで構築されていたので、rpmには含まれていなかったコンパイル時の依存関係があったようです。
ただし、調べてみると、見つからなかったクラスは、スタックトレース内のいくつかのクラスと同じモジュール内にありました。さらに、これは最近ビルドに追加されたばかりのモジュールではありませんでした。これらの事実は、それがMavenの依存関係の問題ではないかもしれないことを示していました。
最終的な解決策: サービスを再起動してください。
Rpmのアップグレードによって、基盤となるjarファイルに対するサービスのファイルハンドルが無効になったようです。次に、サービスは、メモリにロードされていないクラスを見て、そのjarファイルハンドルのリストからそのクラスを検索しましたが、クラスのロード元のファイルハンドルが無効になっていたため、見つけられませんでした。サービスを再起動すると、すべてのファイルハンドルが強制的に再ロードされたため、rpmアップグレードの直後にメモリ内に見つからなかったクラスをロードできました。
その特定のケースが誰かに役立つことを願っています。
このチェーンの中で私の2セント:
classpath に full のパス(/home/user/lib/some_lib.jar
ではなく~/lib/some_lib.jar
)が含まれていることを確認してください。そうしないと、NoClassDefFoundError
エラーが発生する可能性があります。
私は、Androidスタジオを使った私のAndroid開発に関しても同じ問題を抱えていました。提供されている解決策は一般的なもので、私には役立ちませんでした(少なくとも私にとっては)。何時間にも及ぶ調査の結果、私は次のような解決策を見つけました。Androidスタジオを使用して開発を行っているAndroid開発者に役立つかもしれません。設定 - >ビルド、実行、デプロイ - >インスタントラン - >最初のオプションのチェックを外してください。
この変更で私は立ち上がって走っています。これが私の開発者の友達に役立つことを願っています。
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
あなたが最近このようなAndroidスタジオでマルチデックスサポートを追加したならば:
// To Support MultiDex
implementation 'com.Android.support:multidex:1.0.1'
だからあなたの解決策は単にアプリケーションの代わりにMultiDexApplicationから拡張されています
public class MyApp extends MultiDexApplication {
Android Studioで私に起こりました。
私のために働いた解決策:ただスタジオを再起動してください。
クラスに静的ハンドラがあるかどうかを確認してください。もしそうなら、注意してください、ルーパーを持つスレッドでのみ静的ハンドラが開始される可能性があるので、クラッシュはこのように引き起こされる可能性があります。
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);
}
もしあなたが複数のモジュールを使っているのなら、
dexOptions {
preDexLibraries = false
}
ビルドファイルに。
私は RCP(Rich Client Platform) としても知られるEclipseベースのアプリケーションを開発しています。そして私はリファクタリング(plugInから新しいものへの1つのクラスの移動)の後にこの問題に直面しています。
プロジェクトを掃除してMavenを更新しても意味がありません。
問題は Bundle-Activator によって引き起こされていました - /は自動的に更新されていません。新しいPlugInの MANIFEST.MF の下にあるBundle-Activatorを手動で更新したところ、問題が解決しました。
ランタイムクラスローダによってロードされたクラスが、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;
}
});
}
}
この例外のエラーの原因の1つは、Proguardの定義の矛盾から生じる可能性があります。行方不明
-libraryJars "path.to.a.missing.jar.library"。
これは、jarがあるのに、clean&buildが失敗したのに、コンパイルと実行がうまく機能する理由を説明しています。 proguardセットアップで新しく追加されたjarライブラリを定義することを忘れないでください!
Proguardからのエラーメッセージは、jarがまったく存在しないときに到着する同様のantメッセージと混同されやすいため、実際には標準的なものではありません。一番下の部分にのみ、問題を起こしているという小さなヒントがあります。したがって、従来のクラスパスエラーなどの検索を開始するのは非常に論理的ですが、これは無駄になります。
明らかに、NoClassDefFound例外は実行時の結果になります。結果として得られる実行可能jarは、proguardの一貫性の欠如に基づいて構築されています。それを「地獄」と称している人もいます
私のgenymotionデバイスではよく起こります。 Genymotionがインストールされているドライブに十分な量のメモリがあることを確認してください。