April 12, 2020
Estimated Post Reading Time ~

How to Develop/Deploy Cq5 Components/Bundles using just an OSGi Bundle

For those that develop CQ5 components, most people will be familiar with CRXDE or Eclipse to develop CQ5 components and OSGi bundles. The usual unit of deployment is a CRX package either created using the Package Manager or some build script offline using the vault format. The CQ5 package will contain inside it one or more OSGi bundles which are then picked up by the JCR Installer and deploy it to Apache Felix.

There is one other way of deploying code to CQ5 and that is using OSGi bundles with the JCR content bundled as resources inside the bundle itself. This mechanism is used by the applications developed on Apache Sling. Since CQ5 components are essentially Sling applications, I thought I’d describe how to go about doing offline development and deployment of an example CQ5 component using maven.

Let’s start with the pre-requisites:
A local CQ5 instance
Maven
A maven repository with the OSGi bundles OR Install the Archiva Servlet (link) on CQ5

Let’s assume you have these ready.

The first thing you need is a project structure and a pom file.

In my app, I created a project structure as follows:
sample-sling-app/

pom.xml

src/main/java/

com/technomaven/samples/

SomeService.java

com/technomaven/samples/impl

SomeServiceImpl.java

src/main/resources/SLING-CONTENT/

apps/technomaven/components/

testcomponent/

testcomponent.jsp

testcomponent.json

apps/technomaven/templates/

apps/technomaven/config/

etc/designs/my-sling-app/

my-sling-app.json


This source structure will produce the jar file which includes the java classes (contained in src/main/java) and the JCR nodes, properties, and files that constitute the CQ5 components (contained in src/main/resources/SLING-CONTENT). You’ll notice the CQ5 folders for apps and etc/designs/ are there. You can add any other folders there too.

First a look at the pom.xml
<?xml version=”1.0″ encoding=”UTF-8″?>
<project xmlns=”http://maven.apache.org/POM/4.0.0&#8243; xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221; xsi:schemaLocation=”http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd”&gt;
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.sling</groupId>
<artifactId>sling</artifactId>
<version>11</version>
</parent>

<groupId>com.technomaven.sling.samples</groupId>
<artifactId>sample-sling-app</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>Technomaven Sample Sling App</name>

<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-scr-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<id>install-bundle</id>
<goals>
<goal>install</goal>
</goals>

</execution>
</executions>
<configuration>
<instructions>
<Export-Package>com.technomaven.sling.samples.*</Export-Package>
<Private-Package>
</Private-Package>
<Sling-Initial-Content>
SLING-CONTENT/apps/technomaven;overwrite:=true;uninstall:=true;path:=/apps/technomaven,
SLING-CONTENT/content/technomaven;overwrite:=true;uninstall:=true;path:=/content/technomaven,
SLING-CONTENT/etc/designs/my-sling-app.json;overwrite:=true;uninstall:=true;path:=/etc/designs/,
SLING-CONTENT/etc/designs/my-sling-app/;overwrite:=true;uninstall:=true;path:=/etc/designs/my-sling-app
</Sling-Initial-Content>
</instructions>


</configuration>
</plugin>
<plugin>
<groupId>org.apache.sling</groupId>
<artifactId>maven-sling-plugin</artifactId>
<version>2.0.4-incubator</version>
<executions>
<execution>
<id>install-bundle</id>
<goals>
<goal>install</goal>
</goals>
</execution>

</executions>
<configuration>
<slingUrl>http://localhost:4502/system/console</slingUrl&gt;
<user>admin</user>
<password>admin</password>
</configuration>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
</dependency>


</dependencies>
</project>


Most of this is your usual maven configuration of the dependent libraries. If we concentrate on the plugins section, there are three plugins:
maven-scr-plugin
maven-bundle-plugin
maven-sling-plugin


maven-scr-plugin is used to use the scr annotations in the java classes to register or wire the OSGi services.

maven-bundle-plugin uses BND to produce the OSGi bundle with the correct MANIFEST.MF contents. Note the entries in the configuration element. These include the Export-Package, Import-Package, Private-Package headers found in your typical OSGi bundle. The extra element here is the Sling-Initial-Content element which includes declarations of what parts of the bundle should be used to initialise content in the JCR (CRX in our case).

If we look closely, we have several entries delimited by commas:
<Sling-Initial-Content>
SLING-CONTENT/apps/technomaven;overwrite:=true;uninstall:=true;path:=/apps/technomaven,
SLING-CONTENT/content/technomaven;overwrite:=true;uninstall:=true;path:=/content/technomaven,
SLING-CONTENT/etc/designs/my-sling-app.json;overwrite:=true;uninstall:=true;path:=/etc/designs/,
SLING-CONTENT/etc/designs/my-sling-app/;overwrite:=true;uninstall:=true;path:=/etc/designs/my-sling-app
</Sling-Initial-Content>


Each entry contains the location in the bundle, a flag to overwrite in the repository, a flag to install the content on uninstall of the bundle, and the path in the repository that the contents should be written.

The actual contents of SLING-CONTENT can be specified according to the Sling Content Loader mechanism (more detail here)

Each folder represents a folder in CRX. Each node and its children and properties can be defined in a json file.

In the Sling-Initial-Content above, you will notice two entries for /etc/designs/my-sling-app. One for the the /etc/designs/my-sling-app node itself (which is of type cq:Page) and another for the its child (jcr:content) and child nodes and properties of jcr:content.

The third plugin (maven-sling-plugin) is used to install the bundle to Apache Felix in the install phase of mvn execution.

That’s it. Run mvn clean install from commandline and this will be installed on your local CQ5 instance and overwrite your OSGi bundle, /apps/technomaven, and /etc/designs/my-sling-app folders in CRX.

The full package of the code above can be found here. Enjoy.



By aem4beginner

No comments:

Post a Comment

If you have any doubts or questions, please let us know.