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

Reply via email to