NoClassDefFoundErrorは基本的に起こしてはいけないのだが、ライブラリがインストールされているかどうかに依存していてどうしても起きるかどうか分からないと言うこともある。それを回避する話です。
NoClassDefFoundErrorは以下の3つの読み込めないクラスを読み込もうとしたときに起こる。そのエラーは基本的に取得できない。
- staticメンバーの値や関数を呼び出したとき
- クラスのインスタンスを作成しようとしたとき
- クラスを(またはインターフェースを)拡張したクラスの読み込みをしたとき
ソースにするとこんな感じ。以下のソースではコンパイルした後にNodaクラスファイルを削除しています。
public class Test { public static void main(String[] args) { Test t = new Test(); } Test(){ n = null;//null代入はエラーにならない n = new Noda();//インスタンスを作成するとエラーになる。 System.out.println(Noda.mushi);//staticメンバーを読み込むとエラーになる。 new Class2();//これもエラーになる。 } public Noda noda(Noda n){//呼び出さない限りはエラーにならない。 return new Noda(); } Noda n;//宣言ではエラーにならない public static class Class1 extends Noda{}//宣言ではエラーにならない(外部から呼び出されるとエラー) public class Class2 extends Noda{}//内部クラスも宣言ではエラーにならない }
とにかく、メモリにアクセスしたり、メモリを作成したりするとエラーが起こる。
存在するか分からないクラスファイルが無くてもエラー終了させない為には、ClassクラスのforName関数でロード可能かどうかを先に調べておく。
例えば、以下の様にstatic変数でアクセス可能かどうかのフラグを残しておけば、後の処理はENABLEで条件分岐すれば良い。
public static final boolean ENBLE; static{ boolean b=true; try{ Class.forName("Noda"); } catch (ClassNotFoundException e) { b =false; } ENABLE = b; }