felix-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Angelo van der Sijpt <angelo.vandersi...@luminis.nl>
Subject Re: brain teaser - embedded felix / class cast exception
Date Tue, 08 Jul 2008 19:24:38 GMT

On 8 Jul 2008, at 19:19, Dieter Wimberger wrote:

> I guess that 7.0 is the output from the felix classloader. When  
> allowing parent delegation (what Sahoo suggested), then you get the  
> result you were looking for.

The 7.0 is indeed the name of the classloader of bundle ID 7 (the 0 is  
the version; if the bundle gets updated, this number will be  
incremented), which has to be the bundle that exports the  
CacheServiceMain object.

> On 8 Jul 2008, at 18:47, Sahoo wrote:
>>> My parent is what creates the Felix container, so it is  
>>> technically not
>>> in a bundle, but I loaded the same class code in it's jar (since I'm
>>> going to be using it, of course) -- although, design wise, I'm  
>>> using the
>>> <<interface>> not the <<Impl>>, but I short circuited
>>> interface just
>>> to get to the bottom of the riddle...
>> This seems to be the problem. Felix does not use the class that's  
>> loaded by your code, which is running outside Felix. To fix it, you  
>> have to make both Felix and your code use the same class. Since  
>> your code runs before Felix and you probably don't want to use  
>> reflection to use that class, the only option that I can think of  
>> is to configure Felix to use your class by adding org.craig.cache  
>> to the list of packages exported by the parent class loader. The  
>> property name in config.property is:  
>> org.osgi.framework.system.packages. See OSGi documentation for more  
>> details about this property.

True: Felix is a bundle too (that is why you can get its  
BundleContext), the system bundle to be precise. This system bundle  
does import the package from bundle 7 as soon as that class would get  
used. You can get the service reference for the class you want because  
it is possible to resolve the package import from the system bundle  
(that is, if it would not be possible because of e.g. versioning, you  
would not get the service reference).

If you really want to use the service outside of the Felix instance,  
Sahoo's suggestion of delegating to the system classloader seems the  
best way to go.
Still, I think I would package whatever it is you want to be using  
service with as a bundle, and run all code from inside that bundle.

If neither of these is an option, reflection might help you out. For  
instance, if you have a service MyService of which you are sure the  
definitions are identical, but just not loaded by the same  
classloader, you can use a proxy like such:

     final Object object =  

     MyService service = (MyService)  
Proxy.newProxyInstance(MyService.class.getClassLoader(), new Class[]  
{ MyService.class },
         new InvocationHandler() {
             public Object invoke(Object proxy, Method method,  
Object[] args) throws Throwable {
                 Method bridge =  
                 return bridge.invoke(object, args);

Hope this helps,


View raw message