2013-04-30 25 views
6

Ben tamamen emin değilim çünkü ben doğru olanı yaptım emin değilim. Bir web projesi için Eclipse kullanıyorum. com.web.project paketindeki WebProject (duh) diyelim.ServiceLoader.next bir NoClassDefFoundError neden

WebProject'ün çalışma zamanında JAR eklentilerini yüklemesini istiyorum, bu yüzden java.util.ServiceLoader'dan yararlanabileceğimi düşündüm. Bu yüzden, WebProject projesinde, eklentilerin uygulanması gereken tüm yöntemlerle com.web.project.WebProjectPlugin arabirimini oluşturdum.

Sonra bir sınıf klasör olarak kendi Yapı yolunda WebProbject/inşa/sınıfları ekleyerek projeyi PluginProject yarattı:

package com.web.project.plugin; 

import com.web.project.WebProjectPlugin; 

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

Sonra eklenti projesinde bir META-INF/hizmetler klasörünü oluşturulan koymak iç satırında "com.web.project.plugin.TestPlugin" satırını içeren com.web.project.WebProjectPlugin numaralı metin dosyası.

Eklenen derleme/sınıflar klasörüne göz atıp JAR dosyasını sabit sürücüye yerleştirdim. . WebProject yukarı başladığında, şunları yapar:

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 dosyası içinde bulunduğu dizine işaret eden bir File nesnedir iter boş olmadığından İlk başta, srvl işini yapar gibi görünüyor ama Daha sonra iter.next()'a ulaştığında korkunç NoClassDefFoundError'u atar.

Zaten ServiceLoader sınamak için bir eklenti yöneticisi projesi oluşturmayı başardım ve çok iyi çalışıyor, ancak bir web projesi değil, düz bir konsol Java uygulaması. Peki, burada ne yapıyorum?

Biraz şaşkın: nasıl değil com.web.project.WebProjectPlugin için sınıf tanımını bulabilirsiniz, bu çalıştığı aynı projede beri? Kullanmakta olduğum URLClassLoader nesnesi ile bir ilgisi var mı?

Bu, stack trace dur.

cevap

5

sınıf yükleyici belli bir hiyerarşi sizin URLClassLoader

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

A WebProject için ebeveyn classloader beklediğini atama deneyin, böylece üst/alt hieararchy değilse bu sizin sınıfları birbirine görünmez olduğunu olabilir doğru şekilde ayarlanmış.

+0

Bence, Thread.currentThread(). GetContextClassLoader() 'demek istediniz, ama ne olduğunu biliyorsunuz? Sadece iyi çalışıyor! Teşekkürler! – MaxArt

+0

Evet, bunu kastediyorum. Cevabı güncelledim. Teşekkürler! – NilsH

İlgili konular