Craig,

Not sure if you read this document:

   http://cwiki.apache.org/FELIX/launching-and-embedding-apache-felix.html

But this document discusses these issues and touches upon the various solutions/approaches, such as reflection.

However, I am in agreement with the others, your life will be greatly simplified if you can package everything as bundles.

-> richard


Angelo van der Sijpt wrote:
Hi,

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 the 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 = bc.getService(bc.getServiceReference(MyService.class.getName()));

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 = object.getClass().getDeclaredMethod(method.getName(), method.getParameterTypes());
                return bridge.invoke(object, args);
            }
    });


Hope this helps,

Angelo

Reply via email to