0

I want to start OSGI bundle from a OSGI bundle. As you can see this code starts bundle by deploying it from a directory:

private void installStartBundle(BundleContext bc, String location, String name) throws BundleException
        {
            debug("installing " + location + "...");
            Bundle[] all = bc.getBundles();
            for (Bundle bundle : all)
            {
                String l = bundle.getLocation();
                if (l.indexOf(name) != -1)
                {
                    debug("already installed bundle " + bundle.getBundleId() + "|" + bundle.getLocation() + ">" + bundle.getSymbolicName());
                    return;
                }
            }

            Bundle b = bc.installBundle(location);
            debug("starting " + b.getSymbolicName());
            b.start();
        }

I noticed a problem: For example I have a bundle with xml configuration file and main bundle which loads the xml configuration file by deploying it into Felix and accessing the package into the xml bundle.

I can successfully install bundle from a bundle but the package which is exported by the dependency bundle is not accessible. Maybe the deployment procedure is too slow for the bundle loader to find the exported package. Any idea how this can be solved?

P.S can you tell me how I can check if a bundle is successfully deployed in Felix?

Peter Penzov
  • 1,126
  • 134
  • 430
  • 808

1 Answers1

5

Please note that the BundleContext has the following function:

BundleContext.getBundle(String location);

If you use that function, you will not have to iterate through all bundles.

Please check the lifecycle of bundles in OSGi to see how it is installed and started. To get a good picture, visit http://zenit.senecac.on.ca/wiki/index.php/OSGi_Concepts_Bundle_Life-Cycle.

To know what happens exactly after installing the bundle, please see the javadoc of the funciton: http://www.osgi.org/javadoc/r4v43/core/org/osgi/framework/BundleContext.html#installBundle%28java.lang.String,%20java.io.InputStream%29

As much as I remember, the bundle will stay in INSTALLED state after calling this function (sadly it is not clear from the Javadoc for me). You can force resolving the bundle with the following code snippet:

Bundle systemBundle = bundleContext.getBundle(0);
FrameworkWiring frameworkWiring = systemBundle.adapt(FrameworkWiring.class);
frameworkWiring.resolveBundles(Arrays.asList(new Bundle[] {bundle}));

See the javadoc of the resolveBundles function for more information: http://www.osgi.org/javadoc/r4v43/core/org/osgi/framework/wiring/FrameworkWiring.html#resolveBundles%28java.util.Collection%29

Please note that even if you resolve a bundle, other bundles that could wire to the new bundle will not do so if they do not have to. E.g. if they have an optional import-package or they had already wired to other bundle, nothing will happen. To force a re-wiring, you should call FrameworkWiring.refreshBundles function. If it is not clear, which bundles you should pass as parameter, just call refresh with a null parameter.

"I can successfully install bundle from a bundle but the package which is exported by the dependency bundle is not accessible":

I do not know how you got to this conclusion. If you have an optional package import in another bundle, it is possible that you did not force refresh.

After calling start on the bundle (if you have a Fragment bundle, you should not call start, but only refresh), it should get the ACTIVE state. It will stay RESOLVED if there is an exception during calling the BundleActivator or the bundle is a Fragment bundle.

Balazs Zsoldos
  • 6,036
  • 2
  • 23
  • 31