Embedding Third party dependency/OSGi bundle in AEM application hosted in AEMasCS

This post illustrate the ways of embedding third party dependency in AEM maven project.
Steps are mentioned considering the project structure to be followed for AEMasCS while the same can be followed for classic versions too. 


Before we begin, I would like to explain the scenario of including a dependency in our AEM maven project. 
  • When we would like to make use of an API that is not already available in our project, we look for that in maven-central repository and specify the dependency in main pom.xml and desired module's pom.xml file. (Lets say, AWS S3 Java SDK V2 dependency)
  • Upon updating the project in the IDE, we would see our class files (making use of those APIs) are compiled/build successfully without any errors. 
  • Now, in the context of AEM/OSGi environment, when the same package and hence the bundle is deployed to AEM instance, dependencies that we added new might not be resolved/available in the OSGi as a bundle. Something like the below
  • This indicates that the added dependency is resolved in the context of Maven project and is not in the context of OSGi which paves way for the need of OSGi bundle of the desired dependency. 
    • While this is possible with our existing core module itself which makes use of bnd-maven-plugin (plugin in recent archetype versions for building core module), some dependencies which are in turn dependent on other dependencies(referred to as transitive dependencies) could not be resolvable as bundle in OSGi. Hence the need for maven-bundle-plugin. 
Creating an OSGi bundle out of third party non-osgi dependency using maven-bundle-plugin is explained in this blog post which is about building and deploying the OSGi bundle outside project code base as a standalone third party bundle. 

In order to do the same as part of single project code base which should be the case with Cloud Manager deployments in AEM as Cloud Service, have explained two possible ways that can be followed. 

1. If organization has their own Maven Artifact Repository. 

If the organization has publicly accessible Repository Manager (Like Nexus or Artifactory), then 

  • Upload the artifact (OSGi bundle of third party dependency) to Nexus
    • This can be separate activity outside cloud manager / outside the context of AEM project as a standalone separate maven project exclusively for creating and uploading the artifact to our own artifact repository.
  • Using the uploaded artifact in AEM project code base 
    • Register the org specific artifact repository in <repositories> section of main pom.xml file in desired build profile(Example: for local developement, we can make use of autoInstallPackage profile) For Cloud Manager deployment, we can make use of cmBuild profile. 
      • Note Network restricted artifact repository is not currently supported in AEMasCS/ Cloud Manager deployments. However, publicly available password protected artifact repository is supported when configured. Ways of configuring the same is detailed in Official doc
    • Embed the artifact(as available in Nexus by Step 1) in filevault-package-maven-plugin -> <embeddeds> entry of  all module + in <dependencies> section of ui.apps module

2. As a separate module in AEM project code base. 

If there is no org specific artifact repository, then we can have a dedicated module as part of the main project code base. 
  • Along the lines of suggested naming convention in Official doc, we can create module named common.core so that we can centralize all the third party dependencies in this module and use maven-bundle-plugin to build the same.
  • Artifact from this module is then embedded in all module
    • In AEMasCS project/ archetype project with version >= 24, OSGi bundle out of core module is embedded in all module as opposed to ui.apps module (Old project structure)
    •  Same way, we are embedding common.core artifact in all module as highlighted in screenshot.

Code:
Sample pom.xml file that creates OSGi bundle out of AWS S3 Java SDK V2 dependency. This can be used for both the methods except the fact that while using it in second method,
  • Update the groupId, artifactId according to the AEM project name
  • Include the <parent> element (We can copy it from existing core module)
  • Remove the <distributionManagement> entry
During Local development:
  • As part of local development, we should make sure that the OSGi bundle that we are creating out of third party dependency is exporting only the required API/packages (Explicitly list all the packages required in Export-Package entry and not "*")
  • We should also make sure that only our project bundles makes use of the custom bundle that we created. This can be verified by checking the "Importing Bundles" section of our custom OSGi bundle in Felix console.
  • In order to go about above two pointers, when we first develop,
    • Use the desired dependency in main and core/pom.xml and install the project (without OSGi bundle of the respective dependency) -> Our project bundle will be in installed state -> Look for dependencies that are in red/ not resolved -> While creating bundle, explicitly mention those and go from there on till we see the bundle in active state and hence the ultimate functionality (making use of desired dependency) is working.
Note :
Update (on 24 Dec 2021):
For including third party dependency using bnd-maven-plugin, please check -  https://myaemlearnings.blogspot.com/2021/12/embed-third-party-dependency-using-bnd.html

Comments

Post a Comment

Popular posts from this blog

OSGI Factory Configuration implementation

Creation of Template Types for Editable templates