プログラムの実行時にクラスパスにある場合とない場合があるパッケージクラスから拡張されたクラスがあります。依存関係が満たされない限り呼び出されませんが、試行時に NoClassDefFoundError をスローする Java ベリファイアを悩ませているようですプログラムをロードするには、
これを回避する方法はありますか?
プログラムの実行時にクラスパスにある場合とない場合があるパッケージクラスから拡張されたクラスがあります。依存関係が満たされない限り呼び出されませんが、試行時に NoClassDefFoundError をスローする Java ベリファイアを悩ませているようですプログラムをロードするには、
これを回避する方法はありますか?
これを回避する方法はありますか?
実際には、いいえ。サブクラスのロード、リンク、および検証を成功させるには、クラスパスでスーパークラスを使用できる必要があります。これは、クラスを初期化してインスタンスを作成する前に行う必要があります。
スーパークラスが利用可能になるかどうか確信が持てない場合は、サブクラスに対する直接的および間接的な静的依存関係をすべて削除してから、 を使用してサブクラスを動的にロードする必要がありますClass.forName()
。スーパークラスが「欠落」している場合は失敗しますがError
、欠落しているクラスに対処するように設計されている場合、別の例外 ( ではない) が発生し、アプリケーションが続行できる可能性があります。
他のライブラリに応じて「オプションで使用される」コードを持つ Spring などのフレームワークは、「戦略パターン」を使用して、その依存関係固有のコードを「内部クラス」または別のクラスに配置します。
外部クラスをロードして正常に実行できます。NoClassDefFoundError がスローされるのは、内部クラスを試行してインスタンス化する場合のみです。
したがって、外部クラスは通常、使用する 1 つの戦略をインスタンス化 (try-catch) しようとし、それが失敗した場合はフォールバック戦略をインスタンス化します。
public class MyService {
protected MyStrategy strategy;
// constructor;
// -- choose our strategy.
public MyService() {
try {
this.strategy = new ExternalLib_Strategy();
} catch (NoClassDefFoundError x) {
// external library not available.
this.strategy = new Standard_Strategy ();
}
}
// --------------------------------------------------------
protected interface MyStrategy {
public void doSomething();
}
protected static class ExternalLib_Strategy implements MyStrategy {
ExternalLib lib = org.thirdparty.ExternalLib.getInstance(); // linkage may
public void doSomething() {
// ... use the library for additional functionality.
}
}
protected static class Standard_Strategy {
public void doSomething() {
// ... basic/ fallback functionality.
}
}
}