简体   繁体   中英

Embedded osgi framework, how to call service functions?

I have a simple java project, called server. In addition i have a osgi api project which defines an interface BlockProvider. Next i have an osgi declarative service project with a service that implements BlockProvider.

In my java project 'server' i have an embedded osgi framework (felix in my case).

I created an bundleactivator which installs gogo osgi bundles, scr bundle , my api project bundle and the service project bundle.

Works without problem, i can inspect my service bundle.

In my server project i want to see which services implement BlockProvider interface. So i implement a ServiceTracker with "BlockProvider.class.getName()" as second parameter (the filter one).

Works also without problems, getServices() return my service project.

But here comes the catch: i can't call any of the functions on the interface BlockProvider, because the BlockProvider in the 'server' project uses a different classloader (sun.misc.Launcher$AppClassLoader@4e0e2f2a) than the service project (o: yellowblock [6]).

I suspect I'm overlooking something basic here: but how can i call functions of my BlockProvider service that implements my BlockProvider interface?

You can only access services from outside the OSGi framework if the API package is provided by the system bundle / the framework. So you should not install the API bundle and instead use the framework property org.osgi.framework.system.packages.extra to export your API package.

There are two important rules that apply here.

  1. When two bundles communicate via services, they MUST both import the API package from the same bundle . Normally you have a choice of which bundle actually exports the package. The provider of the service could export it, in which case the consumer must import it from the provider. Alternatively, you can have a separate "pure API" bundle exporting the API package, and both the provider and consumer import it from there. (Rarely, the consumer bundle exports the package, which is legal in OSGi but kind of weird design.)

  2. The system bundle — that is, the special bundle that represents the OSGi Framework itself from inside OSGi — cannot import packages from any ordinary bundle. It can only export.

When you embed OSGi, your application code outside of OSGi is seen as part of the system bundle. If you want the system bundle to talk to another bundle via services, then combining the two rules above implies that the API package must be exported by the system bundle. This remains true whether the system bundle is the provider or the consumer of the service.

Hence, the API package must be included on the system classpath of the embedding application, and exported from the system bundle when you setup the OSGi Framework using the org.osgi.framework.system.packages.extra property.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM