For many years the Apache Felix maven-bundle-plugin was the standard plugin used for building OSGi bundle projects in Maven. However, this has changed since the bnd project (which is also used as library inside maven-bundle-plugin) introduced their own Maven plugin, the bnd-maven-plugin. This plugin quickly catched up with most features that maven-bundle-plugin provides, and is always released immediately together with new bnd versions. Thus it is recommended to switch maven projects to the bnd-maven-plugin (also there is no urgent need to do this for stable projects).
This article describes the required steps. It is mainly focused on projects inheriting from the wcm.io AEM Global Parent POM, which contains all basic configuration suitable for Maven bundle projects using either maven-bundle-plugin or bnd-maven-plugin.
Step 1: Update aem-global-parent
Update to aem-global-parent 1.4.0 or later - this version contains the base configuration of the bnd-maven-plugin.
Step 2: Update packaging
Unlike the maven-bundle-plugin the bnd-maven-plugin does no longer use the “bundle” packaging type - change the packaging type to “jar”.
The presence of the maven-bundle-plugin was optional if you had not the need to customize anything. If your Maven project is a bundle project you have to add the bnd-maven-plugin.
The maven-jar-plugin customization is only required due to this unresolved issue: MJAR-193. It cannot be defined in the parent POM as this would break the build of non-bundle Maven projects.
If you want to activate the Semantic Versioning check for the exported API of your bundles, additionally enable the bnd-baseline-maven-plugin. This is usually only required if your bundle contains reusable code that is used by other bundles/projects, not for “normal” AEM project bundles.
If you have defined custom bundle header instructions using the <instructions> configuration configuration option of the maven-bundle-plugin, you have to migrate them to the different syntax of the bnd-maven-plugin.
We recommend to keep the Instructions in the pom.xml instead of using a separate bnd.bnd file. Defining it in the POM allows to inherit (and merge) settings via POM parent hierarchies, and allows to add XML comments (event inside a line split over multiple lines).
The <bnd> configuration option does not support nested sub elements. Instead, it’s just a text file using the notation <Instruction>: <Value>.
You can split a long line into multiple lines by putting \ on the end of each line (also on lines with XML comments!).
It’s usually not required to put <![CDATA[…]]> around your bnd instructions. You might have to escape characters special to XML then, though.
Step 5: Verify Package Exports
The maven-bundle-plugin has a default behavior that always export all packages of the project that do not include “impl” or “internal” somewhere in the package name. This is no longer the case for the bnd-maven-plugin! The bnd-maven-plugin exports only packages that contain a package-info.java with an OSGi @Export annotation or an OSGi @Version annotation (the latter is a special configuration defined in aem-global-parent). This is a useful default setting for shared libraries that should export only those packages really required.
For “normal” AEM application bundles it may be too cumbersome to export each package explicit (especially as all packages containing Sling Models have to be exported to be accessible from HTL scripts). Also it would complicate the migration of existing projects relying on the old behavior. For those projects you can add this bnd instruction to your project’s POM file - example:
<!-- Export all non-internal packages by default -->
Replace io.wcm.samples.* with the topmost package from your project.
Step 6: Check for usage of build-helper-maven-plugin with add-resources goal
In wcm.io-based projects it was usual to apply special resource filtering to JSON files describing AEM client libraries to replace the “long cache key” with the current bundle version and SCM build number at build time. Usage example:
Unfortunately you have to copy the existing resource definitions from the aem-global-parent POM that are relevant for your module as they are not inherited/merged by Maven automatically.
Step 7: Check for optional dependencies
Watch out for maven dependencies in your POM that are declared as “optional”. The maven-bundle-plugin marked the package imports for those automatically as “resolution=optional” - this is not the case, you have to list mark packages yourself - example:
If you want to include a dependency as JAR file you can copy it using maven-dependency-plugin and include it using Include-Resource and Bundle-ClassPath instruction, see example.
Legacy Felix SCR Annotations
The bnd-maven-plugin configured in aem-global-parent does no longer support the deprecated Felix SCR Annotations by default. It is recommended to update your project to make use of the standard OSGI annotations instead. If this is not possible you can add support for them for the bnd-maven-plugin: