java.lang.NoClassDefFoundErrorは、「クラスの定義が見つかりません」というエラーを意味します。

java.lang.NoClassDefFoundErrorは、クラスパスに必要なクラスが見つからず、JVMがそれをメモリにロードできないときにスローされるランタイムエラーです。

java.lang.NoClassDefFoundErrorは、クラスが定義されていないことを示すエラーです。

java.lang.NoClassDefFoundError
  • NoClassDefFoundError is a runtime error, so it’s beyond our application scope to anticipate and recover from this.
  • java.lang.NoClassDefFoundError is a runtime error, it never comes in compile time.
  • It’s very easy to debug NoClassDefFoundError because it clearly says that JVM was unable to find the required class, so check classpath configurations to make sure required classes are not missed.

NoClassDefFoundErrorのクラス図

java lang NoClassDefFoundError Class Diagram

Java.lang.NoClassDefFoundErrorの理由

まず、実行時にNoClassDefFoundErrorが発生するシナリオを再現してみましょう。以下のようなJavaクラスを持っているとしましょう。

public class Data {

	private int id;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}
	
}

上記のクラスは、他のカスタムJavaクラスに依存していないことに注意してください。このクラスは単にJavaの組み込みクラスを使用しています。同じディレクトリ内でDataクラスを使用する別のクラスを作成しましょう。

public class DataTest {

	public static void main(String[] args) {
		Data data = new Data();
		data.setId(10);
		System.out.println("Data Id = "+data.getId());
	}

}

それでは、DataTestクラスをコンパイルして、以下のように実行しましょう。 (Soredewa, DataTestクラス o konpairu shite, ika no yō ni jikkō shimashou.)

scdev:temp scdev$ ls
Data.java	DataTest.java
scdev:temp scdev$ javac DataTest.java 
scdev:temp scdev$ ls 
Data.class	Data.java	DataTest.class	DataTest.java
scdev:temp scdev$ java DataTest
Data Id = 10
scdev:temp scdev$

これまでのところ、すべて順調です。今は、Dataクラスファイルを別の場所に移動し、その後でDataTestクラスを実行してみましょう。再度コンパイルしないでください、なぜならコンパイルエラーが発生するからです。

scdev:temp scdev$ mv Data.java Data.class ../
scdev:temp scdev$ ls
DataTest.class	DataTest.java
scdev:temp scdev$ java DataTest
Exception in thread "main" java.lang.NoClassDefFoundError: Data
	at DataTest.main(DataTest.java:5)
Caused by: java.lang.ClassNotFoundException: Data
	at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	... 1 more
scdev:temp scdev$ 
java.lang.NoClassDefFoundError example

java.lang.NoClassDefFoundErrorの解決方法は何ですか?

上記の例から明らかにわかるように、このエラーの唯一の原因は、必要なクラスがコンパイル時には利用可能であったが、ランタイム時には利用できなくなっていることです。NoClassDefFoundErrorエラーを修正するには、次の点を確認することができます。

  • Check the exception stack trace to know exactly which class throw the error and which is the class not found by java.
  • Next step is to look for classpath configuration, sometimes we compile our classes in Eclipse or some other environment and run in some other environment and we can miss classpath configurations. For example, I can fix above issue easily by adding the directory which contains Data class to the classpath like below.
    scdev:temp scdev$ java -classpath .:.. DataTest
    Data Id = 10
    scdev:tempRemember that earlier I had moved Data class to previous directory.
  • Most of the times, NoClassDefFoundError comes with applications running on some server as web application or web services, in that case check if the required jars are part of the WAR file or not. For example, below maven configuration will not package jar file when generating WAR file.

    javax.servlet
    servlet-api
    3.0.1
    provided
    But we need it for creating a servlet based web application, usually this jar is always part of Tomcat or any other application server.

これで、java.lang.NoClassDefFoundErrorの概要を簡単にご紹介しました。このエラーが発生した場合のアイデアや簡単な修正方法について、十分な情報が得られることを願っています。参考文献:API Doc、Javaにおける例外処理

コメントを残す 0

Your email address will not be published. Required fields are marked *