私が正しいことをしたかどうか完全に確信が持てないので、私は尋ねています。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);
}
pluginsDir
はFile
、JAR ファイルがあるディレクトリを指すオブジェクトです。は空ではないsrvl
ため、最初は がその役割を果たしているように見えますが、 に到達するとiter
dreaded をスローします。NoClassDefFoundError
iter.next()
テスト用のプラグイン マネージャー プロジェクトを既に作成しておりServiceLoader
、問題なく動作しますが、これはプレーンなコンソール Java アプリケーションであり、Web プロジェクトではありません。それで、私はここで何が間違っていますか?
私は少し困惑しています:実行中の同じプロジェクトにあるのに、どうしてのクラス定義が見つからないのでしょうか? それは私が使用com.web.project.WebProjectPlugin
しているオブジェクトと関係がありますか?URLClassLoader
これがスタック トレースです。