AEM as a Cloud Service Code Refactoring Tool: Repository Modernizer
Overview
Adobe Experience Manager (AEM) is now available as a Cloud Service, the cloud-native way of leveraging the AEM applications. For existing users, the transition journey to AEM as a Cloud Service involves three phases — Planning, Execution, and Post Go-live.

We at Adobe, are constantly trying to make the transition journey faster and easier for users. One such initiative is developing code refactoring tools to make existing content (code, package structure, indexes, configurations) compatible to AEM as a Cloud Service.
This article outlines the Repository Modernizer tool which changes existing AEM Maven projects to be AEM as a Cloud Service compatible by ensuring that they respect the split of mutable and immutable content, dependencies are established to create non-conflicting, deterministic deployments and that they are packaged in a deployable structure.
The Repository Modernizer tool modernizes any given project(s) into AEM Cloud Service compatible structure, by creating the following deployment structure :
- The
ui.apps
package, or Code Package, contains all the code to be deployed and only deploys to/apps
. - The
ui.config
package, or OSGi Configuration Package, contains all OSGi configurations. - The
ui.content
package, or Content Package, contains all content and configuration (i.e. all the node definitions not in theui.apps
orui.config
packages). - The
all
container package that ONLY includes deployable artifacts, the OSGi bundle Jar file(s),ui.apps
,ui.config
andui.content
packages as embeds.

Usage
- It is recommended to use this tool via the AIO CLI plugin for code refactoring tools which integrates all the code refactoring tools and minimizes overhead of installation and setup of individual tools (refer to the article Unified Experience for AEM as a Cloud Service Code Refactoring Tools to understand how to install and execute the plugin).
- It can also be executed standalone (see here for more details).
Configuration
Before executing the tool, please go through the expected input configurations and the sample configuration provided here.
How it works
1. Create base project structure
- Create the base template for
all
package and parentpom.xml file
at the root level. - If only single project is configured, create the base template for
ui.apps
,ui.apps.structure
,ui.content
andui.config
packages at the same level. - If multiple projects are configured, create project folders (with the same name as source project) inside which we create the base template for
ui.apps
,ui.apps.structure
,ui.content
andui.config
packages. - If multiple projects are configured, create a base reactor pom for each project.
- Apply the specified
groupId
,artifactId
andversion
in the newly created artifactpom.xml
files. - For each project specified in the configuration, copy all packages with the packaging type
content-package
(other than the packages specified underexistingContentPackageFolder
) from the source. - Copy core bundles as per input configuration and embed them in the
all/pom.xml
.
2. Separate mutable and immutable content
- For each project specified in the configuration, traverse the content of the source packages specified under
existingContentPackageFolder
and separate the mutable and immutable content according to their paths. - The separated content are copied over to the project’s
ui.apps
andui.content
packages as applicable. - Find and move the OSGi configurations from the
ui.apps
package to theui.configs
package (under the path/apps/my-app/osgiconfig
).
NOTE : Conflicts during the above move operation will be reported and conflicting content needs to be moved over manually.
- As per AEM as a Cloud Service best practice, all OSGi configs (except Repo Init OSGi configs) will be translated to
cfg.json
format.
3. Separate filter paths
- For each project specified in the configuration, traverse the content of the source packages specified under
existingContentPackageFolder
and extract the filter paths specified in theirfilter.xml
files. - The filter paths are separated into mutable and immutable paths based on their JCR paths. The separated paths are now added to the project’s
ui.apps
andui.content
packages' filter file as applicable. - In
ui.apps.structure/pom.xml
, define the JCR repository roots in which the project’s code sub-packages deploy into (i.e. enumerate the filter root paths present inui.apps
package'sfilter.xml
). - Add the filter path to
/apps/my-app/osgiconfig
inui.configs
package's filter file.
4. Refactor the pom files
- For each project specified in the configuration, traverse the content of pom files of the source packages specified under
existingContentPackageFolder
and extract the dependency and plugin info. They will be added to theui.apps/pom.xml
file.
NOTE 1: uber-jar
dependencies will be replaced with aem-sdk-api
dependencies
NOTE 2: 3rd party bundle dependencies which are found will be reported, please add 3rd party dependency jar files in the nonadobedependencies
directory (which would serve as a local repository for 3rd party bundles). It will be included in the repository section of the parent pom.
- In
ui.apps/pom.xml
add the dependency for theui.apps.structure
artifact. - In
ui.content/pom.xml
add the dependency for theui.apps
artifact. - In
all/pom.xml
embed the newly createdui.apps
,ui.config
andui.config
artifacts for each project. - In the parent pom file, add the sub-projects info section, and the repository section for including 3rd party dependencies from local repository.
- In the parent pom file, add the dependency and plugin info extracted from the source parent pom.
- Add the parent pom info in the newly created
ui.apps/pom.xml
,ui.content/pom.xml
andui.config/pom.xml
for each project. - Scan the core bundles’ pom files and replace any
uber-jar
dependency withaem-sdk-api
dependency.
Known Limitations
The tool has some known limitations (we are working on addressing them) :
- It does not make any modifications to existing core bundles, apart from replacing
uber-jar
dependencies withaem-sdk-api
dependencies.
Things that would need to be handled manually :
- Conflicts arising during moving content to new packages.
- Missing version info in core bundles will be reported; the version will also need to be added in the dependency section in the
all/pom.xml
. - For core bundles, changes like updating them to use the BND plugin (rather than the old Felix plugin), translating the Felix bundler directives to BND directives need to be done manually.
- 3rd party dependency bundles will be reported, their jar files need to be placed in the
nonadobedependencies
directory which will serve as a local repository.
NOTE : The above mentioned issues will be reported in the result.log
and repository-modernizer-report.md
files generated by the tool. Please go through them after executing the tool to verify that each step has been successfully completed and to find out what needs to be handled manually.
Demo
This demo video shows how to execute the Repository Modernizer tool (to change multiple AEM Maven projects to be AEM as a Cloud Service compatible) via the aio-cli-plugin-aem-cloud-service-migration
.
Contact us
Your feedback is graciously accepted and appreciated!