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
