ClassCastException przy dynamicznie ladowanych klasach

0

Witajcie,

Mam problem i niezbyt wiem, jak go w ogole ugryzc (czyt. czemu sie pojawia):

  1. mam program, ktory laduje z plikow JAR klasy, ktore implementuja (na pewno) interfejs Bazowy (najczesciej nie jest to bezposrednie implementowanie tegoz interfejsu, tylko implementowanie go poprzez implementowanie w klasie interfejsu dziedziczacego po Bazowy)

  2. mam kolekcje, w ktorej trzymam pary: nazwa (kanoniczna) interfejsu implementowanego przez dynamicznie zaladowana klase (interfejs ten na pewno dziedziczy po Bazowy) + klasa, ktora implementuje interfejs, ktorego nazwa jest kluczem

  3. zaladowane klasy pobieraja z tej kolekcji klasy, ktore implementuja potrzebne im interfejsy (dziedziczace oczywiscie po Bazowy)

no i teraz jest problem...

/* Dziedziczacy extends Bazowy */

Dziedziczacy d = (Dziedziczacy) pobierzZKolekcji(Dziedziczacy.class.getCanonicalName());
// to powyzej powoduje wystapienie wyjatku ClassCastException mowiacego o tym, ze nie mozna zrzutowac klasy, ktora jest zwracana z kolekcji (ktora na 100 % implementuje interfejs Dziedziczacy) na Dziedziczacy
// dodam, ze Dziedziczacy nie jest jakos "specjalnie" ladowany z pliku .jar - uznalem, ze chyba jest automatycznie ladowany, jesli klasa ladowana do programu go wymaga...
// Bazowy jest w zrodlach "wspolnych" dla aplikacji glownej oraz klas ladowanych potem dynamicznie i takie cos dziala:
Bazowy b = (Bazowy) pobierzZKolekcji(Dziedziczacy.class.getCanonicalName());
// oczywiscie ta metoda zwraca Bazowy, jako, ze jest to wspolny interfejs, ktory implementuja wszystkie dynamicznie ladowane klasy

Mam nadzieje, ze zrozumiecie o co mi chodzi ;)

//edit: prawdopodobna przyczyna bledu podana w kolejnym poscie.

0

Dodatek:
Gdy ładuję interfejs (w tym wypadku Dziedziczacy) z innego pliku .jar, to przy ladowaniu pliku klasy, ktora go implementuje, ale jest w innym pliku .jar wywala blad, ze nie znaleziono klasy (nawet jesli plik z Dziedziczacy byl "mielony" wczesniej), wiec pewnie jedna blad tkwi w tym, ze jest wiele class loaderow lub w czym pochodnym...

PRAWDOPODOBNA PRZYCZYNA:
Hmm... chyba juz wiem, gdzie jest blad - tworze oddzielny class loader (URLClassLoader) do kazdego pliku w kazdym pliku JAR. Problem w tym, ze nie wiem, jak to rozwiazac inaczej... :( Prosze o podpowiedzi.

Ładowanie pliku odbywa sie u mnie w taki sposob:

foreach(plik .jar w katalogu)
foreach(entry w pliku .jar) rób:
Class<?> c = Class.forName(binaryName, false,
		new URLClassLoader(
		  new URL[] { 
		    new URL("jar:file:/" + filename + "!/")	
		  }
		)
);

binaryName to sciezka obiektu JarEntry z zamienionymi / na . oraz z obcietym ".class", czyli innymi slowy nazwa pakietowa (kanoniczna) klasy.
0

Rozwiazanie:
Trzeba utworzyc jedna instancje URLClassLoader'a zawierajacego wszystkie URLe plikow .jar, z ktorych chcemy zaladowac klasy. Nastepnie ladowac klasy z kolejnych plikow .jar z uzyciem tego class loadera.

1 użytkowników online, w tym zalogowanych: 0, gości: 1