There are more than one way to install a bundle to Apache Sling and Adobe Experience Manager. The methods all can be reduce to three mechanisms. The bundle can be added to the quickstart application itself. The bundle can be added using the Felix GUI or services. The bundle can be enabled by using the Sling JCR Installer. Of these, using the JCR Installer method is good practice and can be considered a design pattern.
Adding a bundle to the quick start (the binaries of the application itself) is non-trivial and is not necessary unless creating fragments that need to load very early in the application start-up cycle. This should only be used by advanced developers.
Maven Sling or AEM developer plugins can add bundles directly to Apache Felix. Felix has an HTTP service for adding bundles. Bundles can be added to Felix using the GUI. Bundles can be installed from an OSGi bundle repository (OBR). It can be added to an install directory on the disk. The advantage to using Felix to directly manage the OSGi bundles is that it is simple and easy for developers to understand. If using the OBR installation, when a bundle is installed it checks its dependencies and will install the dependencies if they are available. That is a nice feature, but the GUI for the OBR is not available but default with out-of-the-box AEM. The reason for this is that AEM package-based. AEM uses packages, not standalone bundles, for installation and updates.
The preferred way to install bundles into Apache Sling and Adobe Experience Manager is to place the bundle into the repository and leverage the Sling JCR Installer to handle installing the bundle.
The Sling JCR Installer monitors directories within the repository that follow a naming convention. When a bundle is added or removed from one of these directories, the Sling JCR Installer will install or remove the bundle based on a set of rules. By default, any directory with the name of “install” is monitored.
In addition, it monitors directories in a way that mimics the way selectors in URLs are processed. A directory whose name is “install” with run modes appended with “.” delimiting the run modes will be monitored by the JRC Installer if those run modes are active. For example, a directory named “install.author” will be monitored if one of the run modes is author. More than one run mode can be added to the name of an install directory. An install directory named, “install.author.dev,” will be monitored if the run modes include both author and dev. Run mode specific install folders are very powerful. The Felix start level that a bundle is installed from repository can be controlled as well. To load a bundle specific to a start level, create a sub-directory in the install directory with the start level number as its name and place the bundle in there.
Sling JCR Installer as a Design Pattern
Packages can place OSGi bundles into the repository, so it can install bundles using JCR Installer. Packages contain many resources needed for functionality in AEM. For example, it can contain JSP, pages, CSS, and configuration for an application. And it can include all bundles that work together. Packages are good because they can be versioned and have dependency of other packages. Packages are easy to track in the Package Manager. They are a very good way to move custom development from one environment. Bundles installed via Sling JCR Installer work with the package model. Bundles installed directly within Felix do not.
Another good way to move content from one environment to another is to use Apache Jackrabbit FileVault. FileVault transports content of the repository. Bundles installed via the Sling JCR Installer can be moved with FileVault.
JCR Installer can do conditional installation based on run modes using named directories. Start levels can be controlled by both Felix-direct installation and JCR Installer.
It is easier to revert to a previous version of an OSGi bundle using JCR Installer. Remove the older version and replace it with the earlier one. The Felix installation method will not totally forget a later version of an OSGi bundle when uninstalled. It is more problematic to revert using the Felix-base installation.
When updating AEM, some updates completely replace the quick start. When this happens, bundles installed directly through Felix will disappear. This can be unsettling if not expected.
One seeming advantage to installing via Felix is that bundles can be installed via an HTTP service. The Sling JCR Installer documentation provides an example of how to install via an HTTP service.
Using the JCR Installer for installing OSGi bundles allows bundles to install via packages and FileVault. It provides an easy way to revert to previous versions of a bundle. Bundles become part of the repository and are retained through backups and upgrades.
The lone exception when bundles should not be installed via the repository is when they need to be loaded very, very early in the application load process. Most developers will not face this problem.
Adobe CQ Help released a very good, detailed, tutorial on how to create packages. Adobe CQ Help | Packaging Adobe Experience Manager 6 applications