Program-Me-Rev
Program-Me-Rev

Reputation: 6624

How to make sure OSGi bundles load in right order

I have a class that programatically starts an OSGi container, loads bundles, then starts them. The problem I am having is that the bundles are not started in the right order. Some bundles get loaded and started before those they are dependent on get started.

How can I make sure that all bundles get started in the right order, not before those they are dependent on?

P.S: Any code improvement suggested on what I have so far are welcome.

Thank you all in advance.

import java.io.File;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.ServiceLoader;

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.launch.Framework;
import org.osgi.framework.launch.FrameworkFactory;

public class App {

    public static void main(String[] args) throws BundleException, URISyntaxException {
        App app = new App();
        app.initialize();
    }

    private void initialize() throws BundleException, URISyntaxException {
        Map<String, String> map = new HashMap<String, String>();

        // make sure the cache is cleaned
        map.put(Constants.FRAMEWORK_STORAGE_CLEAN, Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT);

        map.put("ds.showtrace", "true");
        map.put("ds.showerrors", "true");

        FrameworkFactory frameworkFactory = ServiceLoader.load(FrameworkFactory.class).iterator().next();
        Framework framework = frameworkFactory.newFramework(map);

        System.out.println("Starting OSGi Framework");
        framework.init();

        File baseDir = new File("target/dist-1.0-SNAPSHOT-bin/plugins/");

        loadScrBundle(framework);

        // get all the Bundles from our plugins directory
        File[] fList = baseDir.listFiles();

        for (File file : fList) {
            if (file.isFile()) {
                System.out.println(file.getAbsolutePath());

                if (file.getName().endsWith(".jar")) {
                    framework.getBundleContext().installBundle(file.toURI().toString());
                }
            } else if (file.isDirectory()) {
                // recurse
            }
        }

        for (Bundle bundle : framework.getBundleContext().getBundles()) {
            bundle.start();
            System.out.println("Bundle: " + bundle.getSymbolicName());
            if (bundle.getRegisteredServices() != null) {
                for (ServiceReference<?> serviceReference : bundle.getRegisteredServices())
                    System.out.println("\tRegistered service: " + serviceReference);
            }
        }
    }

    private void loadScrBundle(Framework framework) throws URISyntaxException, BundleException {
        URL url = getClass().getClassLoader().getResource("org/apache/felix/scr/ScrService.class");
        if (url == null)
            throw new RuntimeException("Could not find the class org.apache.felix.scr.ScrService");
        String jarPath = url.toURI().getSchemeSpecificPart().replaceAll("!.*", "");
        System.out.println("Found declarative services implementation: " + jarPath);
        framework.getBundleContext().installBundle(jarPath).start();
    }
}

Upvotes: 1

Views: 1459

Answers (1)

Peter Kriens
Peter Kriens

Reputation: 15372

If you write OSGi code that depends on start order then you do not have an OSGi code ... Anybody I know over the past 18 years that tried to muck with start order had lots of preventable problems with OSGi. Since in OSGi any bundle can start/stop at any time you might be able to get it to work once at startup but any disturbance will kill your code.

If you use OSGi Declarative Services then these problems do not exist. Just translate any time dependency to a service and depend on that service.

Really, get over it, there is no ordering in OSGi ...

Upvotes: 7

Related Questions