-
Notifications
You must be signed in to change notification settings - Fork 7
Request to add Sling Nodetypes to AEM uber jar bundle manifests
AEM Developers working in Maven projects would benefit from having the full product CND embedded in the uber-jar artifacts released by Adobe (-apis
, -obfuscated-apis
, -unobfuscated-apis
), linked by a Sling-Nodetypes
header in each jar's MANIFEST.MF file.
Since the nodetypes in AEM are declared in many separate .cnd
files within various packages and bundles, it would be acceptable to embed each of these files unmodified in the uber jars, and list them all in the Sling-Nodetypes
header as separate, comma-separated paths. But since this may not account for sequential dependencies between CNDs, the ideal solution would be to embed a single monolithic CND file, like the one that is generated by the CRX/de Lite Tools -> Export Node Type
feature, at a relative path within the bundle of SLING-INF/nodetypes.cnd
.
The uber-jar-6.4.1-apis.jar file's META-INF/MANIFEST.MF
file currently begins:
Manifest-Version: 1.0
Bundle-Description: The Adobe AEM Quickstart and Web Application.
Implementation-Title: cq-quickstart
Bundle-SymbolicName: com.day.cq.cq-quickstart-api
Implementation-Version: 6.4.0
Built-By: root
Bundle-ManifestVersion: 2
Bundle-Vendor: Adobe Systems ltd
Once the cnd
is included in the jar file, you would add a Sling-Nodetypes
header like so:
Manifest-Version: 1.0
Bundle-Description: The Adobe AEM Quickstart and Web Application.
Implementation-Title: cq-quickstart
Bundle-SymbolicName: com.day.cq.cq-quickstart-api
Implementation-Version: 6.4.0
Built-By: root
Bundle-ManifestVersion: 2
Bundle-Vendor: Adobe Systems ltd
Sling-Nodetypes: SLING-INF/nodetypes.cnd
While it is possible for members of the AEM community to publish their own jars with the exported nodetype, it is probably Adobe's prerogative to publish this artifact as a part of the officially licensed AEM APIs.
The Sling-Nodetypes
header is a convention established for the Sling JCR Content Loader
, so that bundles containing JCR content can avoid constraint violations when loading initial content without depending on the installation of additional artifacts over different channels, such as via filevault packages.
Even though the uber-jar artifacts are not intended for deployment in an AEM server or other OSGi environment, there are two main use-cases to support adopting this convention regardless, both related to testing JCR-dependent functionality during AEM project builds.
- Unit testing using Sling Mocks
The Sling Mocks unit testing library provides several ResourceResolver mock types. Two of these types (JCR_OAK
and JCR_JACKRABBIT
) support JCR nodetype registration by scanning the classpath for Manifests which declare a Sling-Nodetypes
header, even though the mocks do not require execution within an OSGi framework.
The benefits for AEM developers in this regard would be 1) to allow testing of functionality which directly or indirectly depends on proprietary nodetypes like cq:Page
and 2) to make it easier to test functionality which directly or indirectly depends on Sling nodetypes like sling:Folder
, which may be provided by individual Sling bundles, but whose Java APIs are otherwise already included in whichever monolith uber-jar
dependency is listed as a dependency on the provided
- or test
-scope classpath.
- Package validation using
oakpal-maven-plugin
Because OakPAL constructs an Oak repository from scratch to simulate the installation of a content-package
artifact, it must be provided, in one way or another, all the necessary JCR nodetypes to enforce the same schema constraints that are enforced in the production platform. The oakpal-maven-plugin
has adopted the Sling Mocks pattern for classpath nodetype discovery using the Sling-Nodetypes
header as one of the available methods for providing JCR nodetypes to install prior to observing a package installation in a transient Oak repository (see slingNodeTypes parameter). This would be the easiest method by far for AEM developers who already list one of the uber-jars as a dependency in their bundle modules. A minimal plugin declaration in a content-package
module would look something like this:
<plugin>
<groupId>net.adamcin.oakpal</groupId>
<artifactId>oakpal-maven-plugin</artifactId>
<version>1.1.6</version>
<dependencies>
<dependency>
<groupId>com.adobe.aem</groupId>
<artifactId>uber-jar</artifactId>
<version>6.4.0</version>
<classifier>apis</classifier>
</dependency>
</dependencies>
<configuration>
<slingNodeTypes>true</slingNodeTypes>
</configuration>
<executions>
<execution>
<goals>
<goal>scan</goal>
</goals>
</execution>
</executions>
</plugin>