Update a node property using an AEM bundle

In the previous session, we have seen how to obtain a Resource. We later, translated the Resource into a Page object, and then programmatically obtained its title. We will see one more example. Here, using an AEM bundle, we will write a property to the Page we created. In this case too, we need to use a Resource object to obtain a Session object using which we can save what we write.

Let us start:

  1. Create a new interface: SearchService.java.
    (There is a reason for using this name. In the next session, we are going to discuss about searching.)
  2. Add the following method.
    public void addProperty();.
  3. Create the implementation class: SearchServiceImpl.java
  4. Implement the addProperty() method.
  5. Get the ResourceResolver.
    (Visit the previous post to see what the code accomplishes.)
    Map<String, Object> param = new HashMap<String, Object>();  
    param.put(ResourceResolverFactory.SUBSERVICE, "readService");
    ResourceResolver resourceResolver=null;
    resourceResolver = resolverFactory.getServiceResourceResolver(param);
  6. Obtain the resource.
    Resource pageResource = resourceResolver.getResource("/content/aem-company/jcr:content");

    Note that we need to add the property to the jcr:content node of the page we created.

  7. Translate the resource into a node using the adaptTo() class.
    Node myNode = pageResource.adaptTo(Node.class);
  8. Set a property to the node.
    myNode.setProperty("author", "sunil");
  9. Obtain the session from resourceResolver.
    Session session = resourceResolver.adaptTo(Session.class);
  10. Save the session:
  11. Deploy the bundle.
  12. Add a method in the bundleservice component.
    com.aemcompany.myproject.SearchService searchService=sling.getService(com.aemcompany.myproject.SearchService.class);
  13. Access the page so that the method is called.
  14. Log into CRXDELite.
  15. See the page properties and ensure that the new property is added.
    That’s it. See you soon.

Access a resource property using an AEM bundle

In this session, we will learn about how to access resources using bundles deployed in the Felix console.  After all, for Sling, everything is a resource. We will update the bundle we developed with a method that accesses a node and prints its title. Though it sounds very simple, we will learn about a very important interface ResourceResolverFactory, that helps us to get ResourveResolver. ResourceResolver gets the Resource object that provides the functionalities to manipulate the nodes and its properties. We will also learn about the adptTo() method that helps to translate an object into a different object type.

So, let us start:

  1. Add the following method in HelloService interface:
    public String getPageTitle();
  2. Add the following ResourceResolveFactory reference:@Reference ResourceResolverFactory resolverFactory;
  3. Implement the getPageTitle() method.
  4. Create a hashmap object with a string & object combination as shown below:
    Map<String, Object> param = new HashMap<String, Object>();
  5. Put ResourceResolverFactory.SUBSERVICE and the service associated to the HashMap object.
    param.put(ResourceResolverFactory.SUBSERVICE, "readService");

    This is a new security layer added in AEM on 6.1 version. It means that the resolveResolver object we create is used by a readService process that we would be created later.

  6. Now create a reference to the ResourseResolver.
     ResourceResolver resourceResolver=null;
  7. Create resourceResolver object as shown below:
    resourceResolver = resolverFactory.getServiceResourceResolver(param);

    As I mentioned earlier, for Sling, everything is a resource. Generally, you use Sling APIs for doing any content manipulation. Getting a ResourceResolver object is imperative for accessing the Nodes in Oak, and later doing various operations, such as Create, Read, Update, and Delete (CRUD). You can compare it to creating a connection object in Java to a database.

  8. Now create a resource object using the getResource() method with a path to the company page as argument.
     Resource pageResource = resourceResolver.getResource("/content/aem-company");
  9. Translate the resource into a Page object using the adaptTo() class.
    Page myPage = pageResource.adaptTo(Page.class);

    Note that the method takes the class name to which we want to translate the resource as an argument. We do this operation to avail various APIs associated with various objects, such as Node, Page, and so on. In this case, we use the getTitle() method in the Page object. This can throw a null or Login Failed exception, and that’s the reason we added a try catch block.

  10. Use the following Page method to get the resource title.
    String title = myPage.getTitle();

Update the bundle service component
Update the bundleservice page, so that we can test if the bundle returns the value.

  1. Login to CRXDE LIte.
  2. Update the bundleservice page.
     <%= repositoryService.getPageTitle()%>

Create a service user mapper

  1. Login to System console.
  2. In OSGI Configuration,  search for Apache Sling Service User Mapper Service.
  3. Create a new service mapping as shown below:
  4. The first part is the bundle name. Second part is the service name that we used in the method. (Step: 5) Third part is the system user who can access the service.
    We are yet to create the system user. Let us do that.

Create a system user and provide access rights

  1. Login to CRX Explorer.
  2. Select User Administration > Create System User.
  3. Enter user ID.
  4. Select Yes for creation.
  5. Provide access to the user to avail the paths.
  6. Search for the user. (myUser)
  7. Provide full access to the content path.
  8. Then, Save the user.

Test the component

  1. Access the page we created.
    Note that it displays AEM Company, the title of the node.

Manage Sling requests using Java Servlets

In this session, we will see how to manage Sling requests using Java Servlets. Servlets are programs that run on a Web server and act as a middle layer between a request and a response. You can deploy Servlets in the Felix console and use them for managing the request from clients. An example: you need to print a message for the request coming from a certain path. Something like, “Thanks for the patience – Coming soon,” because the page is not yet ready.

  1. Import the following classes:
    import org.apache.sling.api.SlingHttpServletRequest;
    import org.apache.sling.api.SlingHttpServletResponse;
    import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
    import org.apache.felix.scr.annotations.sling.SlingServlet;
  2. Add the following Sling Servlet annotation:
    @SlingServlet(paths="/customer/casestudy", methods="GET")

    You can also use more generic scr plugin annotation as follows:

        @Property(name = "sling.servlet.resourceTypes", value = "sling/servlet/default"),
        @Property(name = "sling.servlet.methods", value = "GET")
  3. Ensure that the class extends SlingSafeMethodsServlet.This class is used to read data in Sling. Since we extended a serializable class, add the version number associated with a serializable class. It’s not Sling-specific; it is specific to serializable classes in Java.
  4. Create a doGet() method as follows:
    If you don’t have a doGet() method, the response throws an error.
    public void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException
      response.setHeader("Content-Type", "application/json");
      response.getWriter().print("Thanks for the patience. Coming soon!!");
  5. Build the project after deleting the existing bundle.
  6. Check if you can resolve the path to the correct servlet.
    1. Log into the  system/console.
    2. Go to Sling > Sling Servlet Resolver.
    3. Enter bin/casestudy.
  7. Now access the node http://localhost:4502/customer/casestudy.
  8. Note that it displays the response.
    That’s about the session. See you soon.

Here is the complete class:

package com.aemcompany.myproject.impl;
import java.io.IOException;
import org.apache.felix.scr.annotations.sling.SlingServlet;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;

@SlingServlet(paths="/bin/casestudy", methods="GET")
public class ServletResponse extends SlingSafeMethodsServlet{
private static final long serialVersionUID = 1L;
public void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException
response.setHeader("Content-Type", "application/json");
response.getWriter().print("Thanks for the patience. Coming soon!!");

Create configurable parameters in an OSGi component

In this session, you will see how to configure values for various parameters in an OSGi bundle and obtain the same for further processing.
We will also learn about ComponentContext object that helps to interact with a component.

(As usual, it’s a continuation of the previous session. Obtain the latest package and project from GitHub.)

Following are the prerequisites:

  • You should have installed the aem-company package.
  • You should have downloaded the AEM project and would had imported it into Eclipse.
    (Both these packages are available in my GitHub account.)

We will accomplish the following in this session:

  • We will modify the bundle service component that prints “Hello Apache Jackrabbit Oak.” We created the component to see how to print the value returned by a service in a bundle.
  • We will develop a component that will help us to configure the salutation. That is, it prints the salutation (now, Hello), based what we configure. We may configure it to print as “Hi Apache Jackrabbit Oak.


Update the project with the dependent jar files
We need to import org.apache.sling.commons.osgi class. Means, we need to add the corresponding jar to the Maven project.

  1. Go to http://mvnrepository.com/.
  2. Search for org.apache.sling.commons.osgi.
  3. Select the first class displayed.
    Following is the entry that we need in the POM file.
    <!-- http://mvnrepository.com/artifact/org.apache.sling/org.apache.sling.commons.osgi -->
  4. Open the bundle POM and add the following:
  5. Right-click Maven > Update Project.
    This will download the required jar to the project.

Add a property to the component
Add a property that can be configured:

  • Add the following to the class as shown below:
    @Component(immediate = true, metatype = true, label = "Salutation Service")
    @Property(name = "Label", description = "The Salutation", value = "Hello")

    It creates a service with configurable property, The Salutation.
    Default value of salutation is Hello.

Update the project with the logic

  1. Create a protected activate() method.
    Activate method gets executed when a component is activated. It takes a single argument, ComponentContextComponentContext object helps to interact with the execution context of a component. This needs to be called from the activate() method. We will later setting the class variable salutation based on the value entered in the component.
     protected void activate(ComponentContext componentContext)
        this.salutation= PropertiesUtil.toString(componentContext.getProperties().get("Label"),null);

    PropertiesUtil is a utility class that is used converting property types. The componentContext.getProperties().get(“Label”) method gets the value in the Label property; null is the default value. Rest is simple.

  2. Add a getSalutation method that returns salutation.
     public String getSalutation()
       return salutation;
  3. In the HelloService interface, add the method that we just implemented.
    public String getSalutation();

Remove the existing bundle
We are not doing a clean install now. We will handle that topic later.

  1. Log in CRXDE Lite.
  2. Move to aem-company/install.
  3. Delete the bundle.
  4. Now build the project.

Test the component

  1. Let us update the bundle-service component.
  2. Add the following in the default jsp script:
     <%= repositoryService.getSalutation()%>

    The code becomes:

    <%= repositoryService.getSalutation()%> <B><%= repositoryService.getRepositoryName() %> </B>

    Using the sling.getService() method, we created an object to the HelloService interface, and called the methods it exposed.

  3. Go to system console.
  4. Go to the Components tab.
  5. Locate the HellService component.
  6. Select the Configure button.
  7. Enter the label as Hi.
  8. Refresh the web page we created earlier.
    Notice that it has updated.

That’s about the session. You learned how to obtain values from a component using the ComponentContext.
See you soon.


Enable logging for a bundle

In this session, we will see how to enable logging for a bundle. We will later create a logger configuration in Felix console and will specify a file to write the logs. Enabling logging in a bundle helps you a lot while debugging. We will use Simple Logging Facade for Java (SLF4J). It’s an abstraction of various logging frameworks based on Java.

Note that it’s a continuation of my previous session. Refer to the previous videos when in doubt. You can download the sample project from GitHub. You may need aem-company-site-1.0.zip and aem-company.zip.

  1. Let us open the Eclipse project that we have created.
  2. Locate the HelloServiceImpl.java class.
  3. Import org.slf4j.Logger and org.slf4j.LoggerFactory.
  4.  Add the following statement.
    public static final Logger LOGGER = LoggerFactory.getLogger(HelloServiceImpl.class);

    Using the LoggerFactory instance, it creates a logger for the class passed.

  5. Inside the getRepositoryName() method, add the Logger.Info method.
    LOGGER.info("Adding the repository");
  6. Log into Felix console:
  7. Go to Sling > Log Support.
  8. Select Add New Logger.
  9. Provide the logs name. (logs\aem-company.log)
  10. Then, select the logger class name. (com.aemcompany.myproject)
  11. Now access the web page created earlier.
    It has a component that uses this class to print the repository name.
    Means, when we access the page, the method gets executed – resulting a log entry.
  12. Go to the crx-quickstart\logs folder.
    Note that the aem-company log is created.

Convert an AEM Maven project to an Eclipse-based project

In the previous session, we created an AEM project based on an archetype. We explored the project, deployed it into the Felix console, and then accessed the service it exposed. In this session, we will convert the project into an Eclipse project. So that we can import the project into Eclipse. And, later use Eclipse as an IDE for further learning.

Convert project into an Eclipse project
We can use a Maven command to do this.

  1. Navigate to the project directory.
  2. Execute the following command:
    mvn eclipse:eclipse -DdownloadSources=true -DdownloadJavadocs=true

The project is converted into a Maven project.

Import project into Eclipse and create a Run configuration

  1. In Eclipse, select Import > Existing Project Into Workspace.
  2. Navigate to the project directory and select Finish.
    Bundle and Content projects get imported into the current workspace.
  3. Update the POM files of respective projects, so the bundle and content are created in the aem-company project (that we have been working with.)
    In the bundles’s POM, update the Sling URL property as follows:
  4. In the Content POM, change the target configuration from myproject to aem-company:
  5. Create a Run profile.
  6. Select Run > Run Configuration.
  7. Under Maven Build, right-click > New.
  8. Name it as AEM.
  9. Update Base Directory to your project’s base directory.
  10. Add the following:
    Goal: Install
    Profile: AutoInstallBundle
    Save the configuration.
  11. Using CRXDE Lite, navigate to apps/aem-company.
  12. Create a folder named install.
  13. Now run the configuration.

The project is successfully compiled and deployed into Felix console. You can go to CRXDE Lite and check the Install folder that we created now to see the bundle.
(If you didn’t get it correctly, download the project from my GitHub account.)

Create a bundle for AEM using Maven

In this session, you will learn about developing and deploying bundles for AEM development.

(Following is the transcript of the video above. See the video to get the right context. For sample files, visit GitHub.)

Bundles help to modularize Java development using the Open Source Gateway Initiative (OSGi) framework. A bundle is essentially a Jar file that you deploy in the Apache Felix console. Felix console is the OSGi container.

To make it simpler, to accomplish a complex task, you can deploy a bundle in Felix console that runs with AEM, and then avail the services offered by the bundle. We are not going to explore a lot about OSGi bundles. We will see how a bundle can easily be developed, deployed, and used. You need to have installed Maven in your system. I am not going to talk about how it can be done.
There are plenty of information available in the Internet. Please install Maven.

I am on a Windows machine. After installing Maven, if I run mvn in a command prompt, this the the result that I get. You should see something similar if you had a successful installation and you added it to your class path.

I have created directory, aem-company. This is the company name we used for our sample project. Let me move to the directory.

I will run the following command to create an AEM project. (Please refer the video.) The command is long; I have added the command in my GitHub repository.

Using this command, we will create an AEM project using a Maven archetype. Archytype is a project templating toolkit. Basically, it creates a sample project from which you can start your work.
Note that Adobe provides Archetype repository URL for the developers. I don’t want to explain rest of the parameters. It would be too complex for this session. After running the command, a project structure is created.

Let us explore it further. There are two folders: bundle and content. We will see bundle first. It primarily created a Java project. By default, it added the first Java class that you can use as a start.
You can use this project structure to add more classes.

It created an Interface, HelloService. And, it implements a getRepositoryName() method that should return the underlying repository name. In this case, Apache Jackrabbit Oak is the repository we use.

Go to the Impl folder where we have the actual implementation. @service and @content are two JCR annotations we will see later.

The implementation class has a getRepositoryName() implementation that returns the repository name.
Now, let us deploy the project.

Run the following command: mvn -PautoInstallPackage install
Let us wait for it to complete.

Now log into Apache Felix:

Locate the bundle by searching for AEM-Company.
You could see the service we deployed now: com.aemcompany.myproject.HelloService

Let us quickly access the service. I have developed a component that uses the service. Obtain it from my GitHub. I used a JSP page as the component’s default script, since it’s easy to access a Java service in a JSP page.

com.aemcompany.myproject.HelloService repositoryService=sling.getService(com.aemcompany.myproject.HelloService.class);
Hello, <B><%= repositoryService.getRepositoryName() %> </B>

Let us go to the AEM page we created. Drag and drop the component to the page.
Note that it displays the repository name.

Download AEM company training complete package

Download the complete package from my GitHub account. Package name is aem-company-site-1.0.zip. I thought it will help you to learn quickly.
Have a great 2016!!

Access client-side scripts (ClientLib) in AEM

In this post, I will cover an important concept – Client Libraries. Client Libraries are primarily JavaScript libraries that you may need to use while developing components and templates. This is an important concept that we didn’t cover in the first part of the training.

[As usual, the sample package is available in my GitHub account.]

So, let us develop a quiz component to see how client-side libraries are used in AEM. Let me show you what exactly I meant by a Quiz component. See the webpage – it asks you a very basic question: How much is 1 + 1?


After a user selects and submits the answer, it provides a message stating if the answer is correct or not. The code to accomplish this looks like as given below:

<script type="text/javascript" src="check.js">
<FORM><B>How much is 1 + 1? </B><P>
 <INPUT TYPE=hidden name="answer" VALUE="2">
 <INPUT TYPE=radio NAME="options" VALUE="1">1<br>
 <INPUT TYPE=radio NAME="options" VALUE="2">2<br>
 <INPUT TYPE=radio NAME="options" VALUE="3">3<br>
 <INPUT TYPE=radio NAME="options" VALUE="4">4<br>
 <INPUT TYPE=button NAME="Validate" VALUE="Validate" onClick="checkAnswer(this.form)">

When a user clicks the Validate button, the checkAnswer function in check.js is called. (We will see the js later.)

Now, when we covert that into a component, we need to accomplish the following:

  • Authors should be allowed to enter question, options, and an answer. After all, content is created by authors. You are a developer, who develops the component. We have already seen that authors enter content to a component using dialogs. I am not going to elaborate about dialogs this time, though they are an integral part of the Quiz component.
  • After an author enters a question, options, and an answer, we should validate the answer entered by an end user and then show the appropriate message. We need to call a JavaScript function to validate the answer. That’s what exactly I will cover in this post.

It’s not a good practice to save JavaScript into the component’s script directly. We save the script inside a ClientLibrary in AEM. And then, call the script to the component’s page.  I am not going to start from the scratch. See my previous posts to know more about components and dialogs. This where I am:

  • Created a component, named Quiz.
  • Created a touch-optimized dialog that has the following fields: Question, Answer, Option A, Option B, Option C, Option D. (See my previous posts to know the details)
  • Created a js that essentially captures all the variables a user enters in the dialog. (Again see my previous post on the same. I don’t want to repeat that.)
  • In the component’s default script, entered the html code to display questions and options to the end users.

Now, I need to have a JavaScript function to call, when the end-user clicks the validate button. That’s what I am going to show in this video.

  1. Go to the /etc/clientlibs folder.
    You save your client library files here.
  2. Create a cq:ClientLibraryFolder folder named aem-company. (I hope you remember our company name – in this way, we can easily identify the location of all the client library files needed for the project.)
  3.  Add another property, categories which is a string array. Give a name as aemcompany.script.
  4. Create another folder, scripts.
    It’s not a mandatory step. This way, you can provide more modularity.
  5. Create a aemcompany.js file inside. Copy and paste the required script. This is the script you saw at the start of the video.
    function checkAnswer(form) 
      for (var i = 0; i < form.options.length; i++) 
        if (form.options[i].checked)
      if (form.options[i].value == form.answer.value)
         alert("You selected the correct answer!! :)") 
         alert("You selected an incorrect answer!!") 
  6. Create a js.txt file inside the ClientLibrary folder and add the following:

    It says that js file, aemcompany.js, needs to be picked up from the folder scripts. We are done with creating the js file. Now we need to include this into the component.

  7. Open the Quiz component’s default script and add the following:
    <meta data-sly-use.clientlib=”/libs/granite/sightly/templates/clientlib.html” data-sly-call=”${clientlib.all @ categories=’aemcompany.script’}” data-sly-unwrap></meta>Basically, the following scripts add the category that has the JavaScript that we needed.

To test the component we developed:

  1. Basically, the following scripts add the category that has the JavaScript that we needed.
  2. Right-click and select Edit.
  3. Fill the details.
  4. Select OK
  5. Go to the View mode and test.

As usual, I have uploaded the component to the GitHub account.


A quick start to Adobe Experience Manager development

With this post, I am concluding the first learning series on Adobe Experience Manager. The idea is to provide you with a head start if you are new to AEM. I hope it will also help you with the basic concepts if you plan to appear for Adobe Certified Exam (ACE) on AEM component development.

There are 20 blog posts, most of them are associated with a video of 5 to 8 minutes duration. You need to have an AEM install to try out the demos. I have provided you with the sample packages in my GitHub account. In each post, I have specified the package that you need to use. Note that you basically need to install the packages one after another.

Here is a quick overview of the posts:

  1. Why do you need Adobe Experience Manager?
  2. Let us start Adobe Experience Manager
  3. Seeing is believing: Explore the AEM installation directory
  4. Adobe Experience Manager authors, and their templates, and components
  5. Introduction to AEM developers, and their templates and components
  6. Create the first AEM template
  7. Summary – Create templates and use packages
  8. Add the Parsys component to template
  9. Enable components in the Components tab
  10. Apply a design to the AEM Sightly template
  11. Summary: Your first Sightly template
  12. Create your first Sightly component (YouTube component !!!)
  13. Create Adobe Experience Manager dialogs (Add a dialog to the YouTube component)
  14. Get data from a dialog using Sightly (Get a custom URL for the YouTube component)
  15. Add a touch-optimized dialog (for the YouTube component)
  16. Create a design dialog (for the YouTube component)
  17. Learn about Edit Config nodes
  18. The AEM – Sling connection simplified
  19. AEM and OSGi
  20. Access Client-Side Libraries