7

私が正しいことをしたかどうか完全に確信が持てないので、私は尋ねています。Web プロジェクトに Eclipse を使用しています。package では WebProject (duh) と呼びましょうcom.web.project

実行時に WebProject に JAR プラグインをロードさせたいので、java.util.ServiceLoader. そこでcom.web.project.WebProjectPlugin、プラグインが実装する必要のあるすべてのメソッドを使用して、WebProject プロジェクトにインターフェイスを作成しました。

次に、プロジェクト PluginProject を作成し、ビルド パスに WebProbject/build/classes をクラス フォルダーとして追加します。

package com.web.project.plugin;

import com.web.project.WebProjectPlugin;

public class TestPlugin implements WebProjectPlugin {
    // Implementation of the interface methods...
}

次に、プラグイン プロジェクトに META-INF/services フォルダーを作成し、com.web.project.WebProjectPlugin「com.web.project.plugin.TestPlugin」という 1 行を含むテキスト ファイルを内部に配置しました。

追加された build/classes フォルダーをチェックアウトする JAR ファイルをエクスポートし、ハード ドライブのどこかに置きました。WebProject が起動すると、次の処理が行われます。

File[] jlist = pluginsDir.listFiles(new FileFilter() {
    public boolean accept(File file) {
        return file.getPath().toLowerCase().endsWith(".jar");
    }
});
URL[] urls = new URL[jlist.length];
for (int i = 0; i < jlist.length; i++)
    urls[i] = jlist[i].toURI().toURL();
URLClassLoader ucl = new URLClassLoader(urls);

ServiceLoader<WebProjectPlugin> srvl =
    ServiceLoader.load(WebProjectPlugin.class, ucl);
Iterator<WebProjectPlugin> iter = srvl.iterator();
while (iter.hasNext()) {
    WebProjectPlugin plugin = iter.next();
    plugins.add(plugin);
}

pluginsDirFile、JAR ファイルがあるディレクトリを指すオブジェクトです。は空ではないsrvlため、最初は がその役割を果たしているように見えますが、 に到達するとiterdreaded をスローします。NoClassDefFoundErroriter.next()

テスト用のプラグイン マネージャー プロジェクトを既に作成しておりServiceLoader、問題なく動作しますが、これはプレーンなコンソール Java アプリケーションであり、Web プロジェクトではありません。それで、私はここで何が間違っていますか?

私は少し困惑しています:実行中の同じプロジェクトにあるのに、どうしてのクラス定義が見つからないのでしょうか? それは私が使用com.web.project.WebProjectPluginしているオブジェクトと関係がありますか?URLClassLoader

これがスタック トレースです。

4

1 に答える 1

7

親クラスローダーをあなたに割り当ててみてくださいURLClassLoader

URLClassLoader loader = new URLClassLoader(urls, Thread.currentThread().getContextClassLoader());

WebProject はクラス ローダーの特定の階層を想定しているため、親子階層が適切に設定されていない場合、クラスが互いに見えない可能性があります。

于 2013-04-30T08:09:23.540 に答える