2 Replies Latest reply on Nov 20, 2009 4:50 AM by thomas.diesler

    How does bundle resolution work

    thomas.diesler

      Here is a short explanation of how bundle resolution (currently) works.

      The OSGiBundleClassLoadingDeployer creates the package capabilities/requirements that map to package exports/imports respectively. At runtime the MC iterates over all modules, all requirements, all capabilities.

      For every OSGiPackageCapability it callls

      boolean OSGiPackageCapability.resolves(Module reqModule, Requirement requirement)
      


      The initial implementation, that did not use an external resolver would compare the package name and various other constraints. If a match was determined, this method would return true and irrevocably associate the capability with the requirement. Effectively establishing the wire from the package exported to the importer.

      There are various problems with this approach. Conceptually, bundles cannot be resolved by simply looking at a single package import/export combination. If multiple exporters are available the first one this approach would find is not necessarily the one that can be used for the overall bundle resolution.

      Consider this

       BundleC
       exports A, B
       imports A
      
       BundleD
       exports A,
       imports A, B, C
      


      To resolve BundleC the resolver would have two choices. It could either use the self-import from of package A or import package A from BundleD. If it chooses the latter, both bundles cannot resolve because of the missing import of package C.

      Generally, because the resolve algorithm that is currently available in the MC is not yet suitable for the rich OSGi semantics we (i.e. Ales and I ) agreed to work on a pluggable module resolver. A correct resolver can reason about all possible wirings and may need to retry different wirings to find the best resolution. This becomes especially important when we add support for the uses clause on export packages.

      The related issues are

      https://jira.jboss.org/jira/browse/JBKERNEL-54
      https://jira.jboss.org/jira/browse/JBKERNEL-55

      In JBoss OSGi this is captured by

      https://jira.jboss.org/jira/browse/JBOSGI-151

      The current workaround is that there is the notion of a resolver in the OSGi layer that somehow predetermines the wiring, which is triggered from PackageAdmin.resolveBundles

      PackageAdmin.resolveBundles(Bundle[] bundleArr)
      
       // Resolve the bundles through the resolver
       Resolver bundleResolver = bundleManager.getPlugin(ResolverPlugin.class);
       List<OSGiBundleState> resolvableBundles = new ArrayList<OSGiBundleState>();
       for (Resolvable aux : bundleResolver.resolve(unresolvedBundles))
       resolvableBundles.add(OSGiBundleState.assertBundleState(aux.getBundle()));
      


      The OSGiPackageCapability simply picks up the result from the Resolver and does not attempt do compute the resolution itself.

      boolean OSGiPackageCapability.resolves(Module reqModule, Requirement requirement)
      
       // Get the exporter for this requirement
       ExportPackage exporter = bundleResolver.getExporter(reqBundle, packageRequirement.getName());
       if (exporter == null)
       return false;
      


      The call into OSGiPackageCapability.resolves returns false for every combination but the one the Resolver has previously determined. This is of course still very inefficient and not the right place to do it. Apart from that the current BasicResolverImpl is (as the name suggests) indeed very basic (i.e. wrong). However, it allows us to run the OSGi enterprise examples against the MC Framework on all supported target containers, which was the release criteria for Beta4.

      In future that or a similar resolver API would bubble up into the MC layer and become a native part of its module resolution algorithm. For the time being the notion of external resolver however needs to stay in order to make good progress on the OSGi core TCK.

      This has currently highest priority and will result in functionality that allows folks to be able to actually deploy standard OSGi bundles and see them work as they should on all supported target containers.

      An alternative approach would be, to disable the Resolver and somehow still pass all the enterprise osgi examples and functional tests that are there already. This was our first approach, but unfortunately proved infeasible - so the alternative of external resolution came about.

      merci