Liferay DXP OSGI module project dependency resolution

OSGI Module Gradle Project

We have worked on ANT and MAVEN with Liferay in previous versions. In Liferay DXP Gradle has been introduced. It is quite an interesting feature to learn with Liferay development.

Gradle is powerful and wonderful tool, but due to lack of documentation to use with Liferay I sometimes stuck with dependencies resolutions. I explored it further to overcome the dependency resolution blues that often came to my way. I went through many blogs, forums and wikis and came to know some interesting points which I wanted to sum up on one place that might be helpful for the community.

Generally to add dependency in the build.gradle dependencies we do as follows

dependencies {

      .

      .

      compileOnly 'com.fasterxml.jackson.core:jackson-databind:2.6.7.1'

}

In the above declaration what it “compileOnly” task do is , it compile the source code,it doesn’t include the this dependency and it’s transitive dependencies in the jar package that creates problem while deploying the module in the OSGI container as dependency jars are not resolved.

To overcome this scenario we need to include all transitive dependencies in the dependencies declaration. But how do we know what is the dependency tree?

To get the transitive dependencies and their version, there is task which helps a lot at this step. For that go to Liferay module project ,open CMD and execute below task.

gradlew dependencies --configuration compileOnly

This task  prints the dependencies tree as  below.

compileOnly - Compile dependencies for source set 'main'.

:

:

\--- com.fasterxml.jackson.core:jackson-databind:2.6.7.1

     +--- com.fasterxml.jackson.core:jackson-annotations:2.6.0

     \--- com.fasterxml.jackson.core:jackson-core:2.6.7

 

It gives us the idea that jackson-databind-2.6.7.1 depends on jackson-annotations-2.6.0  and jackson-core:2.6.7 those are also need to include in the build.gradle . To instruct build to include these dependencies in the jar package. We need to configure bnd.bnd as follows. Though David has well explained in his blog for below bnd.bnd entries, i want to recall few of them to understand the context properly.

-includeresource:\

      lib/jackson-annotations.jar=jackson-annotations-2.6.0.jar, \

      lib/jackson-core.jar=jackson-core-2.6.7.jar,\

      lib/jackson-databind.jar=jackson-databind-2.6.7.1.jar

Above instructs build to include dependency jars in the module jar package. But to configure OSGI bundle classpath, it should be included as follows.

Bundle-ClassPath: \

      .,\

    lib/jackson-annotations.jar,\

    lib/jackson-core.jar,\

    lib/jackson-databind.jar

 

Above are steps that gives us more control to specify transitive dependencies and their version. But if we want to rely on gradle to fetch transitive dependencies and configure MENIFEST.MF then compileInclude type can be used in the build.gradle as follows.

dependencies {

      .

      .

      compileInclude 'com.fasterxml.jackson.core:jackson-databind:2.6.7.1'

}

In this case if build gradle plugin it not only compile the source code but also include dependency mentioned and it’s transitive dependency in the module jar package.

To get the transitive dependencies and their version included by gradle, go to Liferay module project ,open CMD and execute below task.

gradlew dependencies --configuration compileInclude

It will print the dependency tree of the dependencies that gradle have included in the jar package. In this case we don’t need to configure bnd.bnd, it is done by gradle task in the MENIFEST.MF in module jar.

OSGI Module Maven Project

For a osgi module project created through Liferay IDE as well dependency analysis is little bit same as Gradle project we have seen above.

Assume we have added a dependency in the Module project.

</dependencies>

                                :

                                :

<dependency>

                  <groupId>com.fasterxml.jackson.core</groupId>

                  <artifactId>jackson-databind</artifactId>

                  <version>2.6.7.1</version>

            </dependency>

</dependencies>

 

To get the dependency tree ,execute following goal.

mvn dependency:tree

It will print the dependency tree like below which help us what all transitive dependency of the project  that we have declared in the project pom.

\- com.fasterxml.jackson.core:jackson-databind:jar:2.6.7.1:compile

    +- com.fasterxml.jackson.core:jackson-annotations:jar:2.6.0:compile

    \- com.fasterxml.jackson.core:jackson-core:jar:2.6.7:compile

It gives us the idea that jackson-databind-2.6.7.1 depends on jackson-annotations-2.6.0  and jackson-core:2.6.7 those are also need to mention  in the bnd.bnd file similar to as we did for gradle project above .i.e.

-includeresource:\

      lib/jackson-annotations.jar=jackson-annotations-2.6.0.jar, \

      lib/jackson-core.jar=jackson-core-2.6.7.jar,\

      lib/jackson-databind.jar=jackson-databind-2.6.7.1.jar

 

Bundle-ClassPath: \

      .,\

    lib/jackson-annotations.jar,\

    lib/jackson-core.jar,\

    lib/jackson-databind.jar

 

 

As osgi resolve dependencies in deifferent way based on the entries in MENIFEST.MF so above is another step we need to take care from OSGI point view other than build tools Gradle and Maven dependency resolution. Hope it helps.