2013-04-30 20 views
6

Pytam, ponieważ jestem całkowicie nie, czy zrobiłeś to, co trzeba. Używam Eclipse do projektu internetowego. Nazwijmy to WebProject (duh) w pakiecie com.web.project.ServiceLoader.next przyczyną NoClassDefFoundError

Chcę, aby WebProject ładował wtyczki JAR w czasie wykonywania, więc pomyślałem, że mogę skorzystać z java.util.ServiceLoader. Stworzyłem więc interfejs com.web.project.WebProjectPlugin w projekcie WebProject ze wszystkimi metodami, jakie muszą implementować wtyczki.

Potem stworzył projekt PluginProject, dodając WebProbject/build/klas na swojej drodze budowy jako folder Klasa:

package com.web.project.plugin; 

import com.web.project.WebProjectPlugin; 

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

Potem utworzonego folderu/usługi META-INF w projekcie wtyczki, umieścić plik tekstowy com.web.project.WebProjectPlugin wewnątrz, zawierający jedyną linię "com.web.project.plugin.TestPlugin".

Wyeksportowałem plik JAR, sprawdzając dodany folder build/classes i umieszczając go w dowolnym miejscu na dysku twardym. Kiedy webowy uruchamia się, robi, co następuje:.

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 jest File obiekt wskazując katalogu plik JAR jest w Na początku wydaje się, że srvl ma swoje zadania, ponieważ iter nie jest pusta, ale następnie rzuca przerażającym NoClassDefFoundError po osiągnięciu iter.next().

Udało mi się już utworzyć projekt menedżera wtyczek, aby przetestować ServiceLoader, i działa dobrze, ale jest to zwykła konsola aplikacji Java, a nie projekt WWW. Co ja tu robię źle?

Jestem trochę zaskoczony: w jaki sposób może nie znaleźć definicję klasy dla com.web.project.WebProjectPlugin, ponieważ jest to w tym samym projekcie, który jest uruchomiony? Czy ma to coś wspólnego z obiektem URLClassLoader, którego używam? To jest stack trace.

Odpowiedz

5

Spróbuj przypisywania classloader nadrzędnej do URLClassLoader

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

A webowy oczekuje pewna hierarchia ładowarki klasy, więc to może być, że zajęcia nie są widoczne dla siebie jeśli rodzic/dziecko hieararchy nie jest ustawić prawidłowo.

+0

Myślę, że chodziło o 'Thread.currentThread(). GetContextClassLoader()', ale wiesz co? Działa dobrze! Dzięki! – MaxArt

+0

Tak, mam na myśli to. Zaktualizowałem odpowiedź. Dzięki! – NilsH

Powiązane problemy