Java.Lang.NoClassDefFoundError: クラス エラーを初期化できませんでしたを修正します。
-
Java.Lang.NoClassDefFoundError: クラスを初期化できませんでした
エラーが発生した Java プログラム -
Java.Lang.NoClassDefFoundError: クラスを初期化できませんでした
エラーの考えられる原因 -
Java.Lang.NoClassDefFoundError: Could Not Initialize Class
エラーを根絶するためのソリューション
今日は、別の実行時エラーについて学習します: java.lang.noclassdeffounderror: could not initialize class
. まず、このエラーが発生した Java プログラムを調べて、考えられる理由について議論し、どのコード行がこのエラーを引き起こしているかを突き止めます。
最後に、このエラーを解消するための解決策についても学びます。
Java.Lang.NoClassDefFoundError: クラスを初期化できませんでした
エラーが発生した Java プログラム
コード例:
public class PropHolder {
public static Properties prop;
static {
// write code to load the properties from a file
}
}
コード例:
import java.util.Properties;
public class Main {
public static void main(String[] args) {
// set your properties here
// save the properties in a file
// Referencing the PropHolder.prop:
Properties prop = PropHolder.prop;
// print the values of all properties
}
}
ここでは、PropHolder
と Main
という名前の 2つの .java
クラスがあります。 PropHolder
クラスは指定されたファイルからプロパティをロードし、Main
クラスはプロパティを設定してファイルに保存します。
また、PropHolder
クラスの prop
変数を参照して、すべてのプロパティの値を出力します。
この Java コードをローカル マシンで実行すると正常に動作しますが、スクリプトを使用して Linux サーバーに展開すると動作しません。 なぜそうなのですか? 理由を考えてみましょう。
Java.Lang.NoClassDefFoundError: クラスを初期化できませんでした
エラーの考えられる原因
まず、java.lang.NoClassDefFoundError
を取得することは、クラスが欠落していることを意味するだけではないことを覚えておいてください。 その場合、java.lang.ClassNotFoundException
が発生します。
また、バイトコード (.class
) が欠落しているという意味でもありません (その場合、この java.lang.NoClassDefFoundError: classname
のようなエラーが発生します)。
そのため、サーバーによる java.lang.noclassdeffounderror: could not initialize class
エラーは、クラス ファイルが見つからないことを意味します。 これは、以下にリストされているさまざまな理由によって引き起こされる可能性があります。
-
問題は
static
ブロック (static
初期化子とも呼ばれます) にある可能性があります。 キャッチされていない例外とともに表示され、クラスをロードしようとしている実際のClassLoader
まで発生および伝搬されます。 -
例外が
static
ブロックによるものでない場合は、PropHolder.prop
という名前のstatic
変数の作成中に発生した可能性があります。 -
指定された Java
CLASSPATH
でClass
が使用できない可能性があります。 -
MANIFEST
ファイルのClassPath
属性でClass
が定義されていないときに、Class
コマンドを使用して Java プログラムを実行した可能性があります。 -
このエラーは、
CLASSPATH
環境変数をオーバーライドする起動スクリプトが原因である可能性があります。 -
別の理由として、依存関係の欠落が考えられます。 たとえば、
NoClassDefFoundError
がjava.lang.LinkageError
の子クラスであるため、ネイティブ ライブラリが利用できない場合があります。 -
log
ファイルでjava.lang.ExceptionInInitializerError
を探すこともできます。これは、static
初期化の失敗が原因でNoClassDefFoundError
が発生している可能性があるためです。 -
J2EE 環境で作業している場合、別の
ClassLoaders
でのClass
の可視性により、java.lang.NoClassDefFoundError
エラーが発生する可能性があります。 -
場合によっては、JRE/JDK のバージョン エラーが原因で発生することがあります。
-
たとえば、OpenJDK バージョン 8.x.x を使用して、マシンで何かをコンパイルしたときにも発生する可能性があります。 プッシュ/コミットしますが、他の誰かがその
JAVA_HOME
を 11.x JDK バージョンに設定しました。ここでは、
ClassNotFoundError
、NoClassDefFoundError
などを取得できます。そのため、プログラムがコンパイルされた JDK を確認することをお勧めします。
Java.Lang.NoClassDefFoundError: Could Not Initialize Class
エラーを根絶するためのソリューション
私たちの場合、ClassLoader
は、クラスを読み込もうとしているときに、クラス定義を読み込んでいるときにエラーに遭遇しました。 したがって、静的イニシャライザ内に try-catch
ブロックを配置すると、問題が解決します。
そこでいくつかのファイルを読み取る場合、ローカル環境とは異なることを覚えておいてください。
コード例:
// import libraries
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
// PropHolder Class
public class PropHolder {
// static variable of type Properties
public static Properties prop;
// static block, which loads the properties
// from the specified file
static {
try {
InputStream input = new FileInputStream("properties");
prop = new Properties();
prop.load(input);
} catch (FileNotFoundException ex) {
Logger.getLogger(PropHolder.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(PropHolder.class.getName()).log(Level.SEVERE, null, ex);
}
} // end static block
} // end PropHolder class
上記のクラスでは、static
ブロックで使用する Properties
型の prop
という名前の静的変数を作成しました。 static
ブロック内で、ファイル システム内の指定されたファイルから入力バイトを取得する FileInputStream
のオブジェクトを作成しました。
次に、指定されたファイルからプロパティをロードするために使用される Properties
クラスのコンストラクターを呼び出して、prop
変数を初期化しました。 この static
ブロックは、アプリケーションを実行した後にのみ実行されることを覚えておいてください。
コード例:
// import libraries
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
// Main Class
public class Main {
// main()
public static void main(String[] args) {
/*
instantiate the Properties class, set various
properties and store them in a given file
*/
Properties prop = new Properties();
prop.setProperty("db.url", "localhost");
prop.setProperty("db.user", "user");
prop.setProperty("db.password", "password");
try {
OutputStream output = new FileOutputStream("properties");
prop.store(output, null);
} catch (FileNotFoundException ex) {
Logger.getLogger(PropHolder.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(PropHolder.class.getName()).log(Level.SEVERE, null, ex);
}
/*
reference the `PropHolder.prop` to access the values of
the properties that we set previously
*/
Properties obj = PropHolder.prop;
System.out.println(obj.getProperty("db.url"));
System.out.println(obj.getProperty("db.user"));
System.out.println(obj.getProperty("db.password"));
} // end main()
} // end Main
Main
クラスでは、Properties
クラスをインスタンス化して、さまざまなプロパティの値を設定し、指定したファイルに保存します。 次に、PropHolder.prop
を参照して、db.url
、db.user
、および db.password
プロパティの値にアクセスし、次のようにプログラム出力コンソールに出力します。
出力:
localhost
user
password