Problem: I have a third party Java library that I need to use in my CQ component. It’s available as a standard jar file. I want to drop this in a lib folder somewhere and have access to the classes. But AEM doesn’t support libraries this way. How do I import and use this code?

Solution: AEM manages libraries as OSGi bundles. OSGi bundles are essentially the same thing as standard jar files, but they contain extra metadata. This metadata relates to versioning and dependencies, and is stored in a jar’s \META-INF\MANIFEST.MF file. AEM requires this metadata, so in order to use a third-party jar library in AEM, you must add that to the library’s jar file, turning it into what’s called an OSGi bundle.

How: Our case study will be a Java API for a third-party mailing list manager: Ecwid’s MailChimp API.

Note that if all you want is a quick step-by-step solution, without images or explanations, see here.

Step 0: Since the source code for our third party library happens to be stored in git, and happens to be compiled with maven, we’ll need to install clients for each. I’ll be using the windows command line clients with cygwin.

Step 1: Build and compile the library

> git clone https://github.com/Ecwid/ecwid-mailchimp.git

Note that the URL was simply copied from “clone URL” field on the repository page linked above

> cd ecwid-mailchimp

> mvn clean package dependency:copy-dependencies -DskipTests=true

Note that I skipped the tests because they break without some API key configuration (which we can do later) and copy the dependencies for a reason I’ll explain in the next step.

Step 2: Figure out how to create a OSGi bundle jar file

There are many ways to build a jar as an OSGi bundle. Here’s what we will not be doing

a) Manually writing up the MANIFEST.MF file. This is untenable for even slightly complicated OSGi bundles because the file format is so fickle. And mistakes don’t yield friendly errors.

b) Use a Maven OSGi plugin and modify the project poms. Configuring this the first time can be nearly as complicated as manually building the manifest file.

c) Use bndtools to create one. This is a good tool but is kind of indiscriminate into what it includes as dependencies. This brings us to our next problem.

Problem: OSGi bundles won’t load unless their dependencies are loaded as OSGi bundles.

“Ideal” Solution: Track down each of the dependencies and recompile those as OSGi bundles. Do the same for each of their dependencies, all the way down the chain. In an ideal world, all jars would be OSGi capable. But few libraries are currently packaged this way, and we’re not going to spend this kind of time on code that’s not ours.

Quick and Dirty Solution: Package the main jar and all its dependency jars as a single, combined OSGi bundle. (Note how we explicitly copied those dependency jars in the maven command above). There are downsides, and this defeats some of the points to OSGi dependency management, but it’s the most practical solution for moderately complex libraries.

Tool: Eclipse for ECP/Plug-in Developers

Why are we downloading a specialized version of Eclipse for something seemingly unrelated to what we’re doing? Because it has a fantastic OSGi builder and interface! Download and install the latest version somewhere. Then open it.

Note that you can also just add “Eclipse Plug-in Devlopment Environment” to your existing Eclipse environment.

Step 3: Create OSGi project in Eclipse

New -> Other -> Plugin Development -> Plug-in from Existing JAR Archives

Add External

Select all the jars in the target folder (target\ecwid-mailchimp-2.0.0.1-SNAPSHOT.jar and target\dependencies\*.jar)

Set a project name

Check "Analyze library contents and add dependencies"

Select "an OSGi framework"

Select "standard"

Uncheck "Unzip the JAR..."

Finish

Step 4: Export the project as an OSGi bundle

Right click on project -> Export

Plug-in Development -> Deployable plug-ins and fragments

Select a directory

Click Finish

Open that directory -> Plugin folder

Copy the jar file

Step 5: Install the OSGi bundle into CQ

Open CRXDE

Navigate to apps\(project)\install

Paste jar file

Step 6: Verify OSGi bundle deployed in CQ

Open CQ OSGi Console

OSGi -> Bundles

Type "mailchimp" (or whatever project name was) into search bar and click "Apply Filter"

Use arrow to expand description of bundle

Scroll through imported packages

Note anything that is highlighted in red because it's unresolvable

Go back into eclipse and the OSGi project

Click "dependencies"

Remove the project dependencies under Imported Packages

Step 7: Redeploy OSGi bundle

Export OSGi bundle again from Eclipse as in previous step

Open CRXDE and delete the old OSGi bundle

Copy-paste the new one in

Verify no issues and an Active status within CQ's OSGi console

Step 8: Use it in a component.

Here’s some sample code from a component jsp that consumes this library, along with its position relative to the OSGi jar.

Conclusion:

Adding third party code to CQ the “right way” isn’t necessarily trivial, but using some standard tools can be done without too much overhead. Suggestions and questions are welcome; based on feedback I may be appending or following up on this topic with more details and explanations.

Resources: