Expand my Community achievements bar.

OSGI Bundle Dependency Resolution Issue due to Version numbers

Avatar

Adobe Champion

Hello Everyone,

I have recently come across an issue in handling dependencies between two custom AEM Maven Projects.

Scenario:

ProjectB has a dependency on ProjectA (OSGI dependency). Lets say current version of Project A is 1.0.0 & Project B is 1.0.0.

  • In this case when we build and deploy project A, maven artifact & metadata is updated in nexus to say 1.0.0 as latest for Project A.
  • And while building projectB, maven dependency is resolved as 1.0.0 & after deploying to AEM if we check the system console the import package generated as part of Manifest Header is as follows:

        Import-Package: <ProjectA Package>; resolution:=optional; version="[1.0, 2)"

       This kind of set the version resolution range as 1.0>x<2

We are able to do multiple deployments of ProjectA bundle successfully with version ranging between 1.0>x<2, with no issues/impacts observed on ProjectB.

However, when we change the version number of ProjectA to 2.x.x & deploy it to AEM, ProjectB is impacted. This leads to NoClassDefFoundError for all the class files which has dependency with ProjectA, but in system console the ProjectB bundle status still says "Active".

Is anyone else have come across this issue? Please do share your inputs in resolving this issue.

TIA

Regards,

Lingesh Palanivelu

5 Replies

Avatar

Level 10

YOIu need to make sure you are referencing the correct version. When you update the version of A, you need to make sure B is referencing the modified version. General OSGi concepts like this can be found here -

2.2 OSGi Concepts .

Avatar

Employee Advisor

Hi,

The important thing on bundle version is, that they are not that relevant. Important are the package versions the provide or require.

In your case the problem is the "optional". It means that a dependency is optional, and the bundle will get active even if the requested package in the proper version is not present. If that's a mandantory (non-optional) dependency the bundle will stay on installed until the dependency gets resolved.

You declare a dependency optional when your application can handle the case of non-present code itself. In most cases you don't want to deal with that yourself and let the container handle it for you, and then you choose mandantory dependencies.

To your case: It worked as long as the optional dependency has been resolved; now that package is no longer present and your code cannot handle it. Remove that optional and your bundle should not get active anymore. Or fix the code to make it work without that package being present.

cheers,

Jörg

Avatar

Adobe Champion

Thanks smacdonald2008​,

I have tried this Import-Package option with a version range [1.0.0,10.0.0), however when we build the bundle & deploy it the bundle manifest headers import package still shows [1.X,2). Looks like the mainfest headers are generated based on the latest version of the dependency which is currently in the maven repository.

What we are actually looking at is once Project B is deployed to AEM, it should resolve any future version of Project A automatically(Without having to build & redeploy ProjectB). Is that possible?

For now, we are rebuilding Project B and deploying every time we increment ProjectA version number.

Avatar

Adobe Champion

Thanks Jörg Hoh​,

I have tried removing resolution=optional which makes the bundle to installed state. Can you please provide some more details on the below point? Do you mean to say embedding dependency using <Embed-Dependency> option?

"Or fix the code to make it work without that package being present."

Avatar

Employee Advisor

Embedding the dependency is the wrong approach, unless it's a third party library, which is not available as OSGI bundle.

The manifest headers are build against the package version of the bundles you specified in the pom.xml. And that's the reason why the OSGI community pays so much attention on proper versioning of their bundles.

So solve your problem, build and deploy the project B in a version 1.0; and then add it as a dependency to project A. And whenever you build project A, build against project B with B having the version 1.0. I do that daily and it works flawlessly.

Jörg