2

開発中のアプリケーションのモジュール ローダーでクラスをロードする際に問題が発生しているようです。基本的に、ロードするすべてのクラスは、実際のアプリケーションのパッケージにある別のクラスを拡張します。ここでは、これを Module と呼びます。モジュールは、実際のアプリケーションの外にある別のフォルダーにあります。

ローダーはフォルダーを反復処理し、拡張子 .class を持つ任意のファイルに対してloadFile()メソッドを実行します。すべてのクラスには Module クラスとしてパッケージ宣言があり、クラス ヘッダーにextends Module宣言があります。

これはloadFile()メソッドで、ヘッダーと例外句は除外されています。

String fileName = file.getName();
String className = fileName.replace(".class", ""); //Strips extension
Class<?> aClass = Class.forName(className, true, new URLClassLoader(new URL[] { file.toURI().toURL() }));
Class<? extends Module> modClass = aClass.asSubclass(Module.class);
return modClass.getConstructor().newInstance();

3 行目でClassNotFoundExceptionが発生し続けます。それを過ぎてClassNotFoundExceptionがスローされなかった場合、すべての依存関係は解決されますか?

4

2 に答える 2

1

URLClassLoaderで、ファイルを渡すのではなく、親フォルダーを渡します。ただし、これはクラスがすべて「デフォルトパッケージ」に含まれている場合は正しく機能するため、ロードする.classファイルの先頭にパッケージ宣言を含めることはできません。

デフォルトでは、クラスローダーはクラスを適切に構築するために必要なすべてのクラスのロードもトリガーします。スーパークラス、スーパースーパークラスなどをロードしようとします...すべてのインターフェイスとスーパーインターフェイス、静的フィールドに必要なクラスおよびメソッド、メソッド署名に必要なクラス(戻りタイプとパラメーター)。通常、メソッドによって内部的に使用されるクラスをロードしようとはしません。それらのメソッドを実行するまではそうしません。

ただし、通常、クラスローダーはこれらすべてのクラスを「含む」わけではありません。たとえば、クラスは最終的にjava.lang.Objectから継承され、URLClassLoaderにはObject.classファイルが含まれません。したがって、クラスローダーは親クラスローダーに委任します。

現在、親を指定せずにURLClassLoaderを作成しています。Java7では、少なくとも親はデフォルトで「システムクラスローダー」になります。これは、プレーンJavaアプリケーションを使用していて、コード自体を内部で実行しない限り問題ありません。クラスローダーの特定の階層。ただし、そのコードをWebアプリケーションやOSGIコンテナーなどで実行している場合は、URLClassLoaderに、たとえばThread.currentThread()。getContextClassLoader()やthis.getClass()などに委任する適切な親を指定する必要があります。 .getClassLoader()。

実行時にこれらのクラスを動的にロードする必要があるため、これらすべてが必要になると思います。

于 2012-06-01T22:16:02.030 に答える
1

URLCLassLoaderのドキュメントから:

このクラスローダーは、JARファイルとディレクトリの両方を参照するURLの検索パスからクラスとリソースをロードするために使用されます。'/'で終わるURLは、ディレクトリを参照していると見なされます。それ以外の場合、URLは必要に応じて開かれるJARファイルを参照していると見なされます。

したがって、ディレクトリまたは.jarのいずれかにURLを使用する必要があります

2つの解決策:

  1. ロードしたいクラス名を持つある種のマニフェストを含む.jarファイルをユーザーに提供するように強制します。このアプローチは、Bukkit開発者によって使用されます。過去にこのメソッドを使用したことがある場合、依存関係はすべて.jarファイルにパッケージ化されているため、URLClassLoaderの検索パスにパッケージ化されてロードできる必要があります。
  2. ファイルのディレクトリのURLを使用して、そのディレクトリで.classファイルを検索します。この方法を使用して依存関係が読み込まれるかどうかはわかりません。
于 2012-06-01T21:54:24.683 に答える