Skip to content

Resolving OSGi bundle dependencies

In my early days of building OSGi bundles for AEM, I got used to this message in the error.log:

*INFO* [OsgiInstallerImpl] org.apache.sling.installer.core.impl.tasks.BundleStartTask Could not start bundle com.acme.samples.aem.bundledependency.samples-bundle-dependency-bundle [457]. Reason: {}. Will retry.
org.osgi.framework.BundleException: Unresolved constraint in bundle com.acme.samples.aem.bundledependency.samples-bundle-dependency-bundle [457]: Unable to resolve 457.14: missing requirement [457.14] osgi.wiring.package; (&(osgi.wiring.package=org.apache.commons.beanutils)(version>=1.9.0)(!(version>=2.0.0)))
at org.apache.felix.framework.Felix.resolveBundleRevision(Felix.java:4095)

Click to see the detailed log...

17.12.2016 07:02:04.956 *INFO* [OsgiInstallerImpl] org.apache.sling.audit.osgi.installer Done refreshing 1 bundles
17.12.2016 07:02:04.960 *INFO* [OsgiInstallerImpl] org.apache.sling.installer.core.impl.tasks.BundleStartTask Could not start bundle com.acme.samples.aem.bundledependency.samples-bundle-dependency-bundle [457]. Reason: {}. Will retry.
org.osgi.framework.BundleException: Unresolved constraint in bundle com.acme.samples.aem.bundledependency.samples-bundle-dependency-bundle [457]: Unable to resolve 457.14: missing requirement [457.14] osgi.wiring.package; (&(osgi.wiring.package=org.apache.commons.beanutils)(version>=1.9.0)(!(version>=2.0.0)))
at org.apache.felix.framework.Felix.resolveBundleRevision(Felix.java:4095)
at org.apache.felix.framework.Felix.startBundle(Felix.java:2114)
at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:977)
at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:964)
at org.apache.sling.installer.core.impl.tasks.BundleStartTask.execute(BundleStartTask.java:93)
at org.apache.sling.installer.core.impl.OsgiInstallerImpl.doExecuteTasks(OsgiInstallerImpl.java:847)
at org.apache.sling.installer.core.impl.OsgiInstallerImpl.executeTasks(OsgiInstallerImpl.java:689)
at org.apache.sling.installer.core.impl.OsgiInstallerImpl.run(OsgiInstallerImpl.java:265)
at java.lang.Thread.run(Thread.java:745)
17.12.2016 07:02:04.961 *INFO* [OsgiInstallerImpl] org.apache.sling.installer.core.impl.tasks.RestartActiveBundlesTask Unable to start bundle com.acme.samples.aem.bundledependency.samples-bundle-dependency-bundle [457] : Unresolved constraint in bundle com.acme.samples.aem.bundledependency.samples-bundle-dependency-bundle [457]: Unable to resolve 457.14: missing requirement [457.14] osgi.wiring.package; (&(osgi.wiring.package=org.apache.commons.beanutils)(version>=1.9.0)(!(version>=2.0.0)))

And to the following result, when checking the status of my bundle at http://<aem-host>:<aem-port>/system/console/bundles/<bundle-id>

AEM Web Console - Bundle - Dependency cannot be resolved

Both of them meaning that AEM was unable to resolve my bundle dependencies at deployment time.

If you find yourself in my shoes, you can either

Use classes exported by another bundle

By default, AEM has a lot of OSGi bundles deployed and one of them may be exporting the classes that you’ve been looking for. You just need to find out which versions are being exported and add to your project the correct version as a dependency.

Let’s say that you have a Maven-based project and you want to use Apache Commons Lang. So:

Note: Installing new libraries as bundles will be explored in future posts.

Or embed classes into your own bundle

Apache Felix Maven Bundle Plugin can help you with that!
Suppose that you have a Maven-based project and you want to use Apache Commons BeanUtils. So:

1. Add the dependency to your POM

  • Access https://mvnrepository.com/;
  • Type commons beanutils;
  • Click on Search;
  • Select any version that depends on commons-collections 3.2.1;
  • Copy the content of the Maven tab;
  • Paste into your parent POM, adding <scope>compile</scope>;
  • Paste it into your child POM, removing the tags <version> and <scope>;

2. Instruct the Bundle Plugin to embed the dependency

  • Open your child POM;
  • Locate maven-bundle-plugin <instructions> tag;
  • Insert the following into it:
<!-- embed all compile and runtime scope dependencies -->
<Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>

This sample project shows the issue in action and also the gory details of how to solve it.

For further information on OSGi bundle resolution, please refer to Christian Posta’s article Understanding how OSGI bundles get resolved part I.

And don’t miss my post about transitive dependencies, possible errors and how to fix them!

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *