Adobe Experience Manager Blog

AEM concepts, snippets and implementation

About aanchalsikka

Certified AEM developer and JAVA enthusiast.

Customizing AEM Toolbar


Adding new action to an AEM Assets Toolbar consists of 2 steps:

  1. Configure the new action for the toolbar
  2. Add a client library to execute some operation on clicking the action.

In the following example, we are adding ability to publish and unpublish assets from the Collection view.


Step 1: Resolving the location of toolbar in CRXDE.

A toolbar’s location can easily be resolved via its page URL.

  1. Copy the URL of the page.
  2. Replace “/mnt/overlay” with “/libs” to resolve toolbar’s path. In our current example:
    • Page URL: /mnt/overlay/dam/gui/content/collections/collectiondetails
    • Toolbar’s location: /libs/dam/gui/content/collections/collectiondetail


Step 2: Add the new action to the toolbar

  1. In CRXDE, locate the toolbar via the path resolved in Step-1.
  2. Browse to “<Toolbar’s path>/jcr:content/actions”.
  3. Overlay actions node in “/apps”. This is to ensure that the customization are only done in “/apps” and NOT “/libs”
  4. Add the new required action. In current example, we have copied publish and unpublish actions from:
    • Source:
      • /libs/dam/gui/content/assets/annotate/jcr:content/actions/selection/publish
      • /libs/dam/gui/content/assets/annotate/jcr:content/actions/selection/unpublish
    • Destination:
      • /apps/dam/gui/content/collections/collectiondetail/jcr:content/actions/selection/publish
      • /apps/dam/gui/content/collections/collectiondetail/jcr:content/actions/selection/unpublish
  5. Visit the Collections View. Select an asset. Notice that publish and unpublish actions would now be available. But, clicking on will execute any operation


Step 3: Add clientlibs to execute an operation via the newly added actions

  1. In CRXDE, locate the toolbar via the path resolved in Step-1.
  2. Browse to “<Toolbar’s path>/jcr:content/head/clientlibs”.
  3. Overlay clientlibs node in “/apps”. This is to ensure that the customization are only done in “/apps” and NOT “/libs”
  4. Add the required client library to the “categories” property of “/apps/dam/gui/content/collections/collectiondetail/jcr:content/head/clientlibs”
    • For the current example, we have added following client libraries:
      • dam.gui.admin.publishasset.coral
      • dam.gui.admin.unpublishasset.coral

Node View.PNG

Visit the Collections View. Select an asset. You should now be able to publish/unpublish an asset via Collection view 🙂




cURL execution from Java program


cURL is a tool to transfer data from or to a server, using one of the supported protocols (DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNETand TFTP). The command is designed to work without user interaction.

With AEM, you can use cURL commands to modify repository, download json, access OSGi information etc.

Snippet to download a json file via cURL:

While majority of the AEM’s content information can be downloaded via HTTP connection,  cURL command can be used to download information from AEM’s OSGi console.

In the shared example, we have used cURL to get information about all the bundles installed in AEM.

Snippet to execute a cURL command:

The follwoing snippet contains acURL command that has been converted in a format to be used in Java snippet.

The cURL command used here is meant to lock page “/content/geometrixx/en/toolbar/contacts” :

curl -u admin:admin -X POST -F cmd=”lockPage” -F path=”/content/geometrixx/en/toolbar/contacts” -F “_charset_”=”utf-8” http://localhost:4502/bin/wcmcommand

For more samples of cURL commands, please refer to:

Connecting AEM from remote AEM instance (via JCR API)


The best way to allow communication between two AEM instance is by:

  • Exposing a service from the AEM instance which acts a source of information  (say Source-AEM)
  • Consuming the exported service in the required remote AEM (Consumer-AEM).


In case, you have a use-case where:

  1. A Service cannot be exposed via source AEM
  2. A utility needs to be deployed in Consumer-AEM to access Source-AEM’s information

Then, you can use the following steps to achieve the same.

Please note: AEM does not allow remote connection OOTB. Hence, we would be embedding jcr2dav bundles. No performance testing has been conducted for the shared code.

Step-1: Create a user in Source-AEM Instance.

Create a user in source-AEM Instance with bare minimum access needed by the utility.


Step-2: Add dependencies to your maven project 

Add following dependencies to the maven project of the utility.

Since, the above bundles are not available in AEM, embed dependency for the above bundles in your pom.xml.

Step-3: Access source AEM instance from utlity.

Create an instance of “Jcr2davRepositoryFactory” to access the source AEM Instance.

For the sample code, access the servlet via URL (http://<Processor-AEM-HOST:Processor-AEM-port>/bin/testRemoteConnection), to get list of all components below “/apps/” folder on Source-AEM Instance.

DS Annotations – dependency updates


With AEM 6.2, we can use the new Declarative Service annotations. These are improvements over Felix annotations. Adding the recommendation excerpt from Apache Felix website:

While the Apache Felix Maven SCR Plugin is a great tool (see below), for developing OSGi components using Declarative Services you should use the official annotations from the OSGi R6 specification. The development of the Apache Felix SCR Plugin is in maintenance mode.

The examples and dependencies have been verified on AEM 6.3 Instance

Maven dependency changes:

In order to use the new OSGi annotations, we need to add following dependencies to pom.xml.


Use latest version of mvn-bundle-plugin (>=3.2.0)

For a project upgrading from Felix to DS annotations, you can remove following:

  • All Felix dependencies. Example:
    • org.apache.felix.scr.annotations
    • biz.aQute.bnd
  • Plugins
    • maven-scr-plugin: is required to resolve felix annotations at build time

Code changes:

You can choose to update java files at once, or one-by-one.

  • Incase you wish to modify all files together, then remove felix dependencies and plugins. The IDE would now recognize all the files that need modifcation.
  • However, if you wish to change files one-by-one, then you can keep both DS and Felix dependencies in pom.xml. A bundle with both types of annotations would still be good. Once all the code changes are done, you should remove all felix dependencies.

How to identify the changes:

You can easily identify the files, by looking for package imports of “org.apache.felix.scr.annotations.*”.

We would be using the following packages instead:

  • org.osgi.service.component.annotations.*
  • org.osgi.service.metatype.annotations.*

For more details on code changes involved, please visit the specific links:

Verify annotation resolution

To verify if the DS annotation is generated:

  • decompile the jar created after mvn clean install
  • Check for the Service description available below /OSGI-INF/ folder



DS Annotations – Component, property and configurations


@Component Annotation

An component is a piece of code that is managed by OSGi container. The container would be responsible for its instantiation and management.

A component is activated only after all its service dependencies are satisfied by the container.

Attributes of a component: 


The above table have been noted from:

  • configurationPolicy: The attribute can hold following values of ConfigurationPolicy
    • IGNORE: Always allow the component configuration to be satisfied and do not use the corresponding Configuration object even if it is present.
    • OPTIONAL: Use the corresponding Configuration object if present but allow the component to be satisfied even if the corresponding Configuration object is not present.
    • REQUIRE: There must be a corresponding Configuration object for the component configuration to become satisfied.
  • factory: used to create a configuration factory. More implementation details are available on link.
  • name: The attribute doesn’t support special characters. If invalid, the component will not be registered.
  • property: A replacement for “@Properties felix annotation used at Class-level”.
  • service: registers component as a Service. More implementation details available on link.


To create a component, add @Component annotation to a class. Also, configure its attributes as per your need.

In the following example, we have:

  • @Activate annotation is used to mark a function which would be called when the component activates. The function can have any name.
  • @Deactivate annotation is used to mark a function which would be called when the component deactivates. The function can have any name.
  • Declared a custom property using property attribute.
    • The property value is read from componentContext in @Activate/@Deactivate methods.

More on defining property:

One may also need to declare multiple properties of a component. In such scenarios, declare an array of values for property attribute:

To define multiple values of a property, create each value as a separate element of the property Array.



Creating configurable properties

The annotations described in this section will help you to create Components whose configurations can be edited via OSGi console. To achieve the same:

  1. Create a separate or an inner interface which would hold configurations. In example, we have created Config interface.
  2. Add @ObjectClassDefinition annotation to the interface. Also, add desired attributes
    • name: The name would help you search the configuration in OSGi’s configuration manager.
  3. Add @Designate to the Component that would consume the configurations.  The ocd attribute should refer to the Configuration interface created in Step-2.
  4. Declare properties that you would like to configure via @AttributeDefinition
    • Following image maps annotation attributes with the OSGi UI.osgi.PNG
    • Please note that there are 2 ways to define default values:
      • defaultValue attribute of @AttributeDefinition: The value is displayed to the user, when he/she tries to configure the interface via Configuration manager. OSGi will NOT pick this default value, if no Configuration exists. Thus, when you install a bundle, the output would appear as:default-values.PNG
      • Specifying default value in variable declarartion: The value is displayed to the user, when he/she tries to configure the interface via Configuration manager. OSGi will pick this default value, even if no Configuration exists.

Also, note that we no longer need PropertiesUtil to resolve OSGi configurations. 🙂


Via Declarative Services, the number of annotations have been reduced. For example: @Component annotation is used for:

  • Component
  • Service
  • Servlet
  • Filter etc..

All of the above can be created by utilizing attributes of @Component details. More details are available on specific links



Toggle Field visibility based on dropdown’s value – Coral 3


AEM’s dropdown comes with a simple and useful feature, to toggle visibility of other Dialog fields based on its selection.

An OOTB implementation is available for component “/apps/core/wcm/components/list/v1/list

Let’s quickly check how to configure it (verified on AEM 6.3 with Coral-3 dropdown):

Step 1: Register dropdown that is supposed to show/hide other dialog fields.

Achieved by adding “granite:class” as “cq-dialog-dropdown-showhide”

Show-Hide drodown.PNG


Step 2: Identify the target dialog fields

This is achieved in 2 small steps:

  1. Informing dropdown about the class that all target elements would have, i.e :
    • Add a new child node “granite:data” to the dropdown
    • Add property “cq-dialog-dropdown-showhide-target” as “.<some_class_name>” showhidetarget.PNG
  2. Adding the class to all target dropdown fields, i.e:
    • Add “granite:class” as “hide <some_class_name>” to all target dropdown


Step 3: Define dropdown’s value for which to show the target field

This is achieved in 2 small steps:

  1. Add ‘value’ property to all options of the trigger dropdowndropdown-value.PNG
  2. Declare dropdown value for which to display the target dialog field
    • Add a new child node “granite:data” to the dialog field
    • Add property “showhidetargetvalue” as “<required_dropdown_option_value>” 




AEM Template Editor – Design configuration via policies


In template editors, policies are used to configure component design. Example: component’s design configurations,  allowed components for a container, mapping asset into components etc.

Configuring a template-editor’s policy is similar to a Static template’s design dialog. Following are the steps to define and access a new policy:

Step 1: Create policy configuration dialog

A component’s policy dialog is defined by adding a cq:design_dialog to the component. Example:


Sample .content.xml for design dialog:

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling=""
jcr:title="My Title Component"
    <content jcr:primaryType="nt:unstructured"
        <items jcr:primaryType="nt:unstructured">
            <tabs jcr:primaryType="nt:unstructured"
                <items jcr:primaryType="nt:unstructured">
                        jcr:title="Available Stage types"
                        <items jcr:primaryType="nt:unstructured">
                                <items jcr:primaryType="nt:unstructured">

Step 2: Configuring policy

Once the design dialog is created:

  • Open the template in Structure mode.
  • Click on the component
  • Following button should now be available to configure the design properties.


Policy Storage and sharing:

  • Policies are stored in following location by default:


Policies can be also be stored in /apps or /libs folder. In this case the resource will be resolved in following preference order: /conf, /apps, /libs.

  • Please observe in the policy path, that policies are stored centrally for a project. This enables authors to share a design policy among multiple templates.
  • Template -> policy mapping is done by referring policy via:



       At location:


Step 3: Accessing policy

A component’s policy configuration can be accessed by ContentPolicyManager. Sharing an example below:

import javax.annotation.PostConstruct;

@Model(adaptables = Resource.class)
public class StageModel {
    private ResourceResolver resourceResolver;

    /** The resource. */
    protected Resource resource;

    private String title;

    protected void constructStageType(){
        ContentPolicyManager policyManager = resourceResolver.adaptTo(ContentPolicyManager.class);
        if (policyManager != null) {
            ContentPolicy contentPolicy = policyManager.getPolicy(resource);
            if (contentPolicy != null) {
                title= (String) contentPolicy.getProperties().get("title");

    * @return title
    public String getTitle() {
        return title;