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) :

How to install printer HP 1018 in Windows 10

Printer installation on Windows 10 is always doing automatically, but it’s also possible to do it manually for case when windows unable to idntify the printer.

  1. Press Win + R enter “printui /s /t2” and click OK
  2. Within “Printer Server Properties” click “Add…” and go threw below steps
  3. In “Windows Update” window select Manufacture HP and driver “HP LaserJet 1020“. Then click “Next” -> “Finish

After all of this steps you printer HP 1018 will be installed.

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

AEM start script for developers

In many cases, it’s much simpler to use an external script rather that every time navigate into the crx-quickstart folder and manually clean outdated log files and then manually run start script from bin folder.

Below is my start.bat script file content to automate this actions for Windows:

del /s /q ".\crx-quickstart\logs\*.*"

set CQ_PORT=4502
set CQ_RUNMODE=author,localdev
set CQ_JVM_OPTS=-Xmx2048m -XX:+UseG1GC -XX:-UseGCOverheadLimit -Duser.language=en -Duser.region=US -Duser.timezone=UTC -Djava.awt.headless=true -Dfile.encoding=UTF-8 -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8001

cd ./crx-quickstart/bin
call ./start.bat

MacOS:

#!/bin/sh

echo "Clean AEM logs"
find crx-quickstart/logs/ -type f -delete

echo "Set AEM parameters"
export CQ_PORT="4502"
export CQ_DEBUG_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8001"
export CQ_LOCALE_OPTS="-Duser.language=en -Duser.region=US -Duser.timezone=UTC -Dfile.encoding=UTF-8"
export CQ_RUNMODE="author,nosamplecontent"
export CQ_JVM_OPTS="-Djava.awt.headless=true -Xmx2048m -XX:+UseG1GC -XX:-UseGCOverheadLimit $CQ_LOCALE_OPTS $CQ_DEBUG_OPTS"

echo "Start AEM instance"
crx-quickstart/bin/start "$@"

Place this script at the same level as license.properties and proceed to enjoy of AEM developing process.

How to install Windows JDK without installation

Sometimes we want to keep our system as much clean as possible and do not want to install JDK from exe installer for . Below is a brief instruction on how to do it:

  1. Download JDK from Oracle site – link
  2. Install 7-zip if not already installed
  3. create unpack.bat file at the same folder where JDK from step 1 was downloaded with below content depends on JDK version:
    1. bat file for JDK 8:
      @echo off
      set PATH=%PATH%;C:\Program Files\7-Zip\
      
      rmdir /s /q "%~dp0\jdk-out"
      rmdir /s /q "%~dp0\unpacked-jdk"
      7z x %1 -o"%~dp0\jdk-out"
      cd /d "jdk-out\.rsrc\1033\JAVA_CAB10"
      extrac32 111
      7z x tools.zip -ojdk
      cd /d "jdk"
      for /r %%x in (*.pack) do .\bin\unpack200 -r "%%x" "%%~dx%%~px%%~nx.jar"
      mkdir "%~dp0\unpacked-jdk"
      xcopy /s "%~dp0\jdk-out\.rsrc\1033\JAVA_CAB10\jdk" "%~dp0\unpacked-jdk"
      cd /d "%~dp0"
      cd /d "jdk-out\.rsrc\1033\JAVA_CAB9"
      extrac32 110
      xcopy /s "%~dp0\jdk-out\.rsrc\1033\JAVA_CAB9\src.zip" "%~dp0\unpacked-jdk"
      cd /d "%~dp0"
      rmdir /s /q "%~dp0\jdk-out"
    2. bat file for JDK 9:
      @echo off
      set PATH=%PATH%;C:\Program Files\7-Zip\
      
      rmdir /s /q "%~dp0\jdk-out"
      rmdir /s /q "%~dp0\unpacked-jdk"
      7z x %1 -o"%~dp0\jdk-out"
      cd /d "jdk-out"
      7z x tools.zip -ojdk
      cd /d "jdk"
      for /r %%x in (*.pack) do .\bin\unpack200 -r "%%x" "%%~dx%%~px%%~nx.jar"
      mkdir "%~dp0\unpacked-jdk"
      xcopy /s "%~dp0\jdk-out\jdk" "%~dp0\unpacked-jdk"
      cd /d "%~dp0"
      rmdir /s /q "%~dp0\jdk-out"
  4. start above script from command line with single parameter (name of downloaded JDK exe installer file). For example:
    unpack jdk-8u152-windows-x64.exe

    or

    unpack jdk-9.0.1_windows-x64_bin.exe

Continue reading “How to install Windows JDK without installation”