AEM dialog with extraClientlibs – do not shot yourself in the foot

AEM dialog with extraClientlibs – do not shot yourself in the foot
The below steps will help you to avoid common mistakes during implementation

There is a common case when we have to extend the AEM component dialog with custom JS code for some cases: field custom validation, to load external data, update field value on any condition, and so on.

Everything is going well until we have a few components or JS logic is not greater than the “hello world” component. But when the project grows alongside with components number we will face dependency hell.

In the scope of components dialogs, we have to keep in mind that every custom include of “extraClientlibs” will live on the page until page reload therefore JS functions could easily break logic in other dialogs during the page editing.

The below steps will help you to avoid common mistakes during implementation:

  1. DO not include every custom JS client library into the cq.authoring.dialog category:
    categories="[cq.authoring.dialog]"

    This ClientLibs category has to be used ONLY for utility methods that could be used across all dialogs and wouldn’t break anything.

  2. Every component dialog with custom JS code have to be placed in a separate category, easy to use package or folder path as a category name, this prevents category name overlap:
    categories="[project-a.components.product.wizzard.authoring]"
  3. Make a rule to put validation that we are working with the required dialog at the JS beginning, if not – bypass the execution:
    (function (document, $) {
    
    "use strict";
    
    const DIALOG_RESOURCE_TYPE = "project-a/components/product/wizzard";
    
    function isTargetDialog($formElement, dlgResourceType) {
    	const resourceType = $formElement.find("input[name='./sling:resourceType']").val();
    	return resourceType === dlgResourceType;
    }
    
    $(document).on("dialog-ready", function () {
    	const $formElement = $(this).find('coral-dialog form.foundation-form');
    	if (!isTargetDialog($formElement, DIALOG_RESOURCE_TYPE)) {
    		console.debug("Skip the listener, not a ", DIALOG_RESOURCE_TYPE, " dialog.");
    		return;
    	}
    	...
    });
    })(document, Granite.$);

As we can see these three steps will help to keep code clean and maintainable.

OAK Query aborted

Every AEM developer faced with below exception which means that we are exceeded the limit of nodes for reading:

java.lang.UnsupportedOperationException: The query read or traversed more than 100000 nodes. To avoid affecting other tasks, processing was stopped.
	at org.apache.jackrabbit.oak.query.FilterIterators.checkReadLimit(FilterIterators.java:70)
	at org.apache.jackrabbit.oak.plugins.index.Cursors.checkReadLimit(Cursors.java:67)
	at org.apache.jackrabbit.oak.plugins.index.lucene.LucenePropertyIndex$LucenePathCursor$1.next(LucenePropertyIndex.java:1730)
	at org.apache.jackrabbit.oak.plugins.index.lucene.LucenePropertyIndex$LucenePathCursor$1.next(LucenePropertyIndex.java:1711)
	at com.google.common.collect.Iterators$7.computeNext(Iterators.java:646)
	at com.google.common.collect.AbstractIterator.tryToComputeNext(AbstractIterator.java:143)
	at com.google.common.collect.AbstractIterator.hasNext(AbstractIterator.java:138)
	at org.apache.jackrabbit.oak.plugins.index.Cursors$PathCursor.hasNext(Cursors.java:216)
	at org.apache.jackrabbit.oak.plugins.index.lucene.LucenePropertyIndex$LucenePathCursor.hasNext(LucenePropertyIndex.java:1751)
	at org.apache.jackrabbit.oak.query.ast.SelectorImpl.next(SelectorImpl.java:432)
	at org.apache.jackrabbit.oak.query.QueryImpl$RowIterator.fetchNext(QueryImpl.java:824)
	at org.apache.jackrabbit.oak.query.QueryImpl$RowIterator.hasNext(QueryImpl.java:851)
	at org.apache.jackrabbit.oak.jcr.query.QueryResultImpl$1.fetch(QueryResultImpl.java:98)

In this situation, we can:

  • define the oak index for a query
  • try to redesign taxonomy of a repository or structure if it might be improved
  • update oak indexes to cover the query
  • use oak:Unstructured instead of nt:unstructured and sling:Folder instead of sling:OrderedFolder in a case where an order is not required
  • etc.

During the development, if we want to skip this error for a while we can increase LimitReads and LimitInMemory parameters for OAK Query Engine:

  1. navigate to  QueryEngineSettings
  2.  increase selected parameters:
  3. this is for development stage only, please, do not push this on production

Links to resources for help:

  1. Oak Index Definition Generator

  2. Best Practices for Queries and Indexing

AEM digital assets installation

There is a common case when we have to install digital assets on AEM. The easiest way to do that is to make a package with the required assets and install it. Below are the installation steps:

  1. Make a package with digital assets and deploy them on AEM package manager.
  2. Stop the com.day.cq.workflow.launcher.impl.WorkflowLauncherImpl – otherwise you will get stuck on rendition workflow.
  3. Install package from p.1
  4. Start the com.day.cq.workflow.launcher.impl.WorkflowLauncherImpl

These steps allow importing assets on AEM quickly with renditions.

Enable AEM Javadoc hints

To consume the whole power of IDE we must use Javadoc hints. Below is a short “how-to” on how to enable these hints for AEM 6.4:

  1. Open “Project structure” (short-key on Windows: Ctrl + Alt + Shift + S):
  2. Find the “Maven: com.adobe.aem:uber-jar:apis:6.4.4” (or another uber jar which you are using for the project) and click plus icon with the Earth

  3. Put the “https://helpx.adobe.com/experience-manager/6-4/sites/developing/using/reference-materials/javadoc/index.html” as a documentation URL.

After all of these actions you’ll be able to see API doc hints (on Windows with Ctrl + Q) :

Fix Java warnings

At past time I’m faced with some unexpected behavior on windows environments. The issue occurs when I’m tried to execute java code which communicate with my windows machine: find-bugs maven plugin or IntelliJ IDEA

Symptom:

[java] WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0x80000002. Windows RegCreateKeyEx(…) returned error code 5.

How to fix: create HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Prefs and
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\JavaSoft\Prefs keys

Continue reading “Fix Java warnings”

Find out AEM information

List of AEM URLs where we could find some useful information:

  1. Installed AEM version: http://localhost:4502/system/console/status-productinfo
  2. AEM Run Mode:
    1. Open http://localhost:4502/system/console/bundles
    2. Navigate to Status -> Sling Settings menu

Split Apache OAK stores

Split Apache OAK stores

Overview

One of big projects drawbacks is a size of Apache OAK which is growing very fast due to big amount of assets , binary files, background processes which are care about repository data consistency, updates and so on. Of cause we can use compaction every week but there is exists another approach – split segment and blob store out of Tar files (which is an OOTB store implementation). One of the available option is to split NodeStore and BlobStore. More about BlobStore you can read here – click. Continue reading “Split Apache OAK stores”

Sling, Git, Windows and Filename too long

There is a common error on Windows systems when you are working with GIT – Filename too long:

error: unable to create file contrib/extensions/distribution/sample/src/main/resources/SLING-CONTENT/libs/sling/distribution/install.publish/impersonate-reverse/org.apache.sling.distribution.packaging.impl.exporter.AgentDistributionPackageExporterFactory-impersonate-reverse.json: Filename too long

What does it means?

It means that by default GIT on Windows has a 260 characters limit due to system limitations (not all Windows apps are properly working with long file names). This can be critical if you will try for example will try to clone Sling application.

Solution

To remove this limitation we should open Windows Power Shell or CMD as administrator and execute command below:

git config --system core.longpaths true

This command will enable long path support and now we could maintain path up to 32,767 characters. For more information you can read this article.

How to simplify AEM UI developing

In AEM very often we need to synchronize content (html, css, dialogs, nodes and so on) between local AEM instance  and development environment. We can achieve this in a few ways:

  1. deploy content bundle every time when we need content refresh with maven (common approach)
  2. use some IDE with built-in functionality for synchronization (Eclipse with Sling IDE plugin, Brackets)

There is also exists another way which I’m referrer to synchronize content – to use Jackrabbit FileVault (VLT) which introduces a JCR repository to filesystem mapping.

Let me show in few steps how to configure it (I believe all console commands are self-explained): Continue reading “How to simplify AEM UI developing”