5

抽象クラスを使用して、人々が独自の実装を作成できるようにするアプリケーションがあります。これらの実装をディレクトリから .class-files としてロードします。現在、私はこの解決策を持っています:

File classDir = new File("/users/myproject/classes/");

URL[] url = { classDir.toURI().toURL() };
URLClassLoader urlLoader = new URLClassLoader(url);

String filename;
for (File file : classDir.listFiles()) {
    filename = string.getFilenameWithoutExtension(file);
    if (filename.equals(".") || filename.equals("..") || filename.startsWith("."))
        continue;

AbstractClass instance = (AbstractClass)urlLoader
    .loadClass("org.mypackage." + filename)
    .getConstructor(ConfigUtil.class, DatabaseUtil.class, StringUtil.class)
    .newInstance(config, database, string));

    instance.doSomething();
}

ご覧のとおり、クラスを正しくロードするには、クラスが配置されているパッケージを指定する必要があります。パッケージを省略すると、

 java.lang.NoClassDefFoundError:
     MyClass (wrong name: org/mypackage/MyClass)

エラー。

さて、アーキテクチャの視点から、他の人が設計したクラスをロードするときに MY パッケージにコンパイルする必要があるのは、非常に不適切な設計だと思います。

だから私はあなたに尋ねます:クラスが存在するパッケージを指定せずに、ファイルシステムからクラスをロードできる方法はありますか?

4

2 に答える 2

3

はい; インターフェイスを実装します (または注釈を使用します)。

次に、任意のクラス スキャン ライブラリを使用して (これについては、このような SO の質問がたくさんあります)、問題の特定のクラスをロードします。「Java クラス スキャン」または「Java プラグイン メカニズム」を検索すると役立ちます。

また、 Java Plugin Frameworkを使用して、多少の手間を省きたい場合もあります。もう維持されているかどうかはわかりませんが、人々がまだそれを使用していることは知っています。

于 2012-02-08T14:53:06.927 に答える
1

ServiceProviderを使用して、 不明な実装をロードできます。

于 2012-02-08T14:56:10.960 に答える