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