Zdravím,
stejné třídy nahrané různým classloaderem nejde navzájem přetypovávat. Pro
použití OSGi rozhodně nemusíte dělat žádnou magii s classloadery. OSGi
classloadery to řeší pravděpodobně pomocí rodičovských classloaderů. Z
tohoto důvodu taky u classloaderů v Javě platí, že se normálně hledá třída u
rodičů a teprve až pak v potomkovi. Pokud budete mít rodičovská classloader
A a dva classloadery B a C, které budou oba mít A jako rodiče, v A budete
mít definován interface I, pak můžete v B použít implementaci I z
classloaderu C – protože ten interface I je společný, je nahraný
classloaderem A. Tohohle principu využívá i OSGi, jenom tam asi nebude
stromová struktura classloaderů, ale nějaká složitější.

Ve vašem případě je problém asi v tom, že máte interface pravděpodobně
nadefinován znovu i v bundlu. OSGi asi nepoužívá pro nahrávání tříd
strategii parent-first (která by si vynutila stromovou strukturu
classloaderů a tedy i závislostí), takže najde dřív definici toho interface
ve svém classloaderu, než ve vašem. Ty společné věci musíte nechat jen ve
společném classloaderu, v tomto případě ve vaší aplikaci.

S pozdravem

Filip Jirsák


2011/2/10 Zdenko Vrabel <[email protected]>

> Ahojte,
>
> V ramci experimentovania s OSGi som sa dostal do situacie s ClassLoaderom,
> z ktorej sa neviem vymotat. Ide o to, ze kazdy Bundle v ramci OSGi ma
> vlastny classloader. Ja som OSGi (konkretne Felix) embeddol do jednej svojej
> aplikacie a chcel som pouzit jeden service. Problem je ten ze moja aplikacia
> (dajme tomu reprezentovana jednou Main triedou) ma svoj ClassLoader a
> service zase svoj. Dosledok toho je to ze ziskam referenciu na service ale
> neviem ju castnut na konkretny interface.
>
> Napriklad:
>
> ServiceReference ref = .... //referencia na implementaciu ICommand
> interface-u
> Object osgiService = felix.getBundleContext().getService(ref);
> ICommand command = (ICommand) osgiService; //class cast exception
>
> Dovodom je to ze ICommand.class.getClassLoader() !=
> osgiService.getClass().getClassLoader().
>
> Mna by zaujimalo ako to riesi OSGi classloadrami? Akoto oni dokazu? Je
> mozne zobrat referenciu na class z jedneho loadra a hodit ju do druheho?
> Skusal som pouzit :
>
>
> Thread.currentThread().setContextClassLoader(osgiService.getClass().getClassLoader());
>
> co by malo nahradit cely classloader ale bohuzial bez uspechu.
> ICommand.class.getClassLoader() stale vrati stary classloader.Priznam sa ze
> zalezitosti okolo classloadra su mi trosku zahadou a chapem len ten hlavny
> princip classloadra. To ci je mozne do classloadra dostat nieco ine z
> druheho classloadra mi je zahadou.
>
> Dakujem velmi pekne za kazdu radu, kazdy postreh.
>
>

Odpovedet emailem