Creating Custom Node Type in JCR
In one of our project, we had to create custom node types. In this blogpost, we’ll talk about the various ways of creating the Custom Node Type and deploying it across multiple instances. We’ll be using AEM 5.6.1 as our CQ server.
A. Creating and Registering the Custom Nodetype
There are broadly following three ways of creating custom node types.
- Using Node Type Administration console.
- Programmatically
- Using Package Manager
We’ll discuss them one by one :
- Using Node Type Administration Console
- Using CND files.
The Compact Namespace and Node Type Definition (CND) notation provides a compact standardized syntax for defining node types and making namespace declarations. The notation is intended both for documentation and for programmatically registering node types. Existing documentation can be followed for creating the CND file.
Go to Node Type Administration console, click on Import Node Type, copy/paste the CND file in the textarea, keep “Automatically register nodetype” checkbox and “Automatically register defined namespaces” checked. Click on submit and your custom node type will be registered.
- Without using CND files
Go to Node Type Administration console,click on Create Node Type and enter the details about Node Name , child Node defintions , property definitions , supertypes etc. Click on the [Register Node Type] link at the bottom of the page to register this newly created Node type. Check the nodetype in Node type Administration console. Below is the screenshot for more details :
- Programmatically
We can register the nodetype programmatically as well.- Using CND file.
We can use JCR Commons CndImporter to register it. Following is the code snippet to regsiter it. Create a CND file say
nodetypes.cnd
having the definition of the new node type. Make this file as a part of the bundle.[java]public class CustomNodeTypeExample {
// some code
session = slingRepository.loginAdministrative(null);
InputStream fis = CustomNodeTypeExample.class.getResourceAsStream("/nodetypes.cnd");
NodeType[] nodeTypes = CndImporter.registerNodeTypes(new InputStreamReader(fis), session);
for (NodeType nt : nodeTypes) {
LOGGER.info("Registered: " + nt.getName());
}
session.save();
// some code
}
[/java]- Without using CND file.
We can use JCR API to create a new node type and register it. Following is the code snippet to register it.
[java]session = slingRepository.loginAdministrative(null);
NodeTypeManager manager = (NodeTypeManager)session.getWorkspace().getNodeTypeManager();
NamespaceRegistry ns=session.getWorkspace().getNamespaceRegistry();
ns.registerNamespace("ig","http://www.intelligrape.com/CustomNode");
// Create node type
NodeTypeTemplate nodeTypeTemplate = manager.createNodeTypeTemplate();
nodeTypeTemplate.setName("ig:testNodeType");
// Create a new property
PropertyDefinitionTemplate customProperty1 = manager.createPropertyDefinitionTemplate();
customProperty1.setName("ig:Name");
customProperty1.setRequiredType(PropertyType.STRING);
PropertyDefinitionTemplate customProperty2 = manager.createPropertyDefinitionTemplate();
customProperty2.setName("ig:City");
customProperty2.setRequiredType(PropertyType.STRING);
// Add property to node type
nodeTypeTemplate.getPropertyDefinitionTemplates().add(customProperty1);
nodeTypeTemplate.getPropertyDefinitionTemplates().add(customProperty2);
/* Register node type */
manager.registerNodeType(nodeTypeTemplate, true);
session.save(); [/java] - Using Package Manager
We can register node type via package manager as well . In Package Manager, upload a CQ package containing custom nodetypes.cnd
and install it. Check that the custom nodetypes are registered in Node Type Administration console.
Troubleshoot :
- After registering the nodetype, make sure it is visible in Node Type Administration console. If not registered, check the
error.log
for more insight. - CND file should be in proper format to avoid unwanted errors.
- Java 7 introduced a stricter verification and changed the class format a bit — to contain a stack map, used to verify that code is correct. If you are using java 7, pass these parameter
-XX:MaxPermSize=512m -Xmx1520m -XX:-UseSplitVerifier
while starting the instance from command line. Refer this link for more details.
B. Deploying the Custom Nodetype across multiple instances
If we have enabled clustering, then our multiple author and publish instances will be running on separate machines. We would want the new node type to be visible in all the instances. It can be done via two ways :
- If we are programmatically registering the new node type , then deploying the bundle will simply make it visible across all the instances.
- Whenever a new node type gets registered in repository, three files gets updated .
custom_nodetypes.xml
at<CQ author instance directory>/crx-quickstart/repository/repository/nodetypes
will contain the definition of new node type.ns_idx.properties
andns_reg.properties
at<CQ author instance directory>/crx-quickstart/repository/repository/namespaces
will have the details of the new namespaces added. Copy/Pasting these files to all the instances at the specified location will make it visible. Note that this will require an instance restart.
Creating custom node types is scenario driven. The use cases are very rare and the process itself is costly. You can follow below link for more details.
https://forums.adobe.com/thread/985062
The most important reason for using custom node type at all is for efficient observations which means you might get a use case where you have to observe changes in a certain part of the repository, based on which you can perform certain tasks e.g based on a node type you want to trigger Events, Launch Workflows etc. You can achieve the same using existing node types which might be getting used in the several parts of the repository (some of which you don’t want to observe), hence will lead to unwanted results.
Hello,
You have hit the bull’s eye with the thorough explanation backed by working code snippets. However, I would like to understand the use-case behind this.
Do we ever need to create custom node types?
-Namit