2013-04-30 6 views
6

私は完全にではないので質問しています私は正しいことをしたと確信しています。私はWebプロジェクトのためにEclipseを使用しています。パッケージcom.web.projectのWebProject(duh)としましょう。ServiceLoader.Next NoClassDefFoundErrorを発生させます

実行時にWebProjectでJARプラグインをロードしたいので、私はjava.util.ServiceLoaderを利用できると思っていました。そこで私はプラグインが実装しなければならないすべてのメソッドを持つWebProjectプロジェクトにインタフェースcom.web.project.WebProjectPluginを作成しました。

は、それから私は、クラスフォルダとしてのビルド・パスにWebProbject /ビルド/クラスの追加、プロジェクトPluginProjectを作成しました:

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"という唯一の行が含まれています。

JARファイルをエクスポートして、追加されたbuild/classesフォルダをチェックアウトし、ハードドライブのどこかに配置しました。 。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は、JARファイルが入っているディレクトリを指すFileオブジェクトですiterが空ではないので、最初は、srvlはその仕事をしているようだが、それはiter.next()に達すると、恐れたNoClassDefFoundErrorを投げます。

私は既にServiceLoaderをテストするためのプラグインマネージャプロジェクトを作成していますが、うまく動作しますが、WebプロジェクトではなくプレーンなJavaアプリケーションです。だから、私はここで間違って何をしているのですか?

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

これはstack traceです。

答えて

5

はあなたURLClassLoader

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

A WebProjectは、クラスローダーの特定の階層を期待し、それは、親/子hieararchyがない場合は、あなたのクラスがお互いに表示されていないことであるかもしれないし、親クラスローダを割り当ててみ正しく設定してください。

+0

あなたは 'Thread.currentThread()。getContextClassLoader()'を意味すると思いますが、何を知っていますか?それはうまく動作します!ありがとう! – MaxArt

+0

はい、私はそれを意味します。私は答えを更新しました。ありがとう! – NilsH

関連する問題