First, why are you starting the bundles in one of the bundles? For
one, the frameworks are usually persistent - Equinox certainly is.
So, what you'll find is that the second time you start up the process
- assuming you don't clean the installation- the bundles will already
be started. So, this is a bad thing to do right off the bat.
Second, as Peter points out, OSGi is a dynamic environment. So, to
make this robust, not error prone and not difficult to maintain, you
should be using service trackers to get your services. e.g.
protected void ensureServices(BundleContext context) {
ServiceTracker tracker = new ServiceTracker(context,
IMyService.class.getCannonicalName(), null);
tracker.open();
Object myService = tracker.waitForService(60 * 1000); // wait 60
seconds for the service to initialize
if (myService == null) {
// shutdown
}
}
My third point is that you shouldn't block the Activator.start()
method, so you'd do:
public void start(final BundleContext context) {
new Thread(new Runnable() {
public void run() {
ensureServices(context);
}
}).start();
}
There are more sophisticated things you can do as well, but they all
ground out to much the same thing as above - i.e. looking in the
registry for a service, timing out.
On Apr 30, 2009, at 12:46 AM, Eugen Reiswich wrote:
Hi OSGi-devs,
I have the following problem with osgi services. We develop
basically applications where dynamic is not an issue. So what I
would like to make sure in my application is that all services are
registred properly at start up - if not, the application will be
shut down. In addition to that I want to reuse my bundles in RCP
applications so any concept must also be applicable for RCP
applications.
Say I have two bundles:
1. org.mycompany.service (contains a service interface)
2. org.mycompany.serviceimpl (contains the service implementation
and registers withing his activator an osgi-service)
What we do within the service bundle is this:
public void start(BundleContext context) throws Exception {
Bundle[] bundles = context.getBundles();
// find the implementation for the service bundle
for (Bundle bundle : bundles) {
if
("org.mycompany.serviceimpl".equals(bundle.getSymbolicName())) {
// service impl found
if (bundle.getState() != Bundle.ACTIVE) {
bundle.start();
}
}
}
// check if servicimpl has registred service properly
ServiceReference serviceReference = context
.getServiceReference(IMyService.class.getName());
if (serviceReference == null) {
// shut down application
}
...
From my point of view this is pretty error prone and difficult to
maintain. Is there a best practice approach how I can make sure that
all services are registered properly at start up of my application?
How can I start my serviceimpl bundles in RCP application as no one
depends on this bundle which is why the are never started?
We have spend now a lot of time to find solutions for this problem
but they all seem to be improvable.
Regards,
Eugen
_______________________________________________
OSGi Developer Mail List
[email protected]
https://mail.osgi.org/mailman/listinfo/osgi-dev
_______________________________________________
OSGi Developer Mail List
[email protected]
https://mail.osgi.org/mailman/listinfo/osgi-dev