Liferay Development

Liferay Consulting

Liferay Training

Your Trusted Liferay Solutions Partner

Saturday, March 7, 2020

Adding Third Party Non OSGi Jars to Liferay OSGi module


Liferay is using OSGi module framework and in real world we may not get all java libraries implementations as OSGi module. Sometimes we may need to add non OSGi jars to Liferay OSGi module. Liferay Module Framework provided a way to add external non OSGi jars in Liferay OSGi module. OSGi bnd tools will be taking care of internal configuration.
  1. The package that Liferay module is using was not available as OSGi module.
  2. The package that Liferay module is using was not exported by Liferay Portal Bootstrap Module.
  3. The package that Liferay module is using was not exported by Liferay Portal Global Class Loader.
  4. The package that Liferay module is using was not exported by any of your custom modules and that already deployed in Liferay Module Framework.

The package imported in Liferay module is satisfying the above criteria then we have to go for adding third party non OSGi jars to Liferay OSGi module.

Take the example that your module need to use apache poi libraries to provide xl sheet related functionality. These jars are non-OSGi and it’s not exported by any of Liferay OSGi framework.

Following are the steps to add Third Party non-OSGi jars

Gradle Liferay OSGi Module

Module Source


Case:1 Add Jar and Its all dependencies

Use “compileInclude” scope dependencies in “build.gradle”, rest of the things will be taken care by gradle build process.

Compile Include configuration is transitive. It will be embedded jar and its dependencies in module lib directory. It will refer all jar references in module MANIFEST.MF “Bundle-ClassPath” header and packages are specified in Private-Package header.

Compile Include will not consider the optional dependencies and if module required optional dependencies then follow the Case:2

Example “build.gradle”


dependencies {
            compileInclude  group: 'org.apache.poi', name: 'poi', version: '4.1.2'
            compileInclude  group: 'org.apache.poi', name: 'poi-ooxml', version: '4.1.2'
            }




Case:2 Explicitly specify JARs in  module bnd file

In this case we will use gradle compile scope and bndincluderesource” header to specify jar and its dependencies (if required).

Option: 1

This option will add specified third-party jars in specific directory in the module(in the jar package) and jar references are specified in MANIFEST.MF “Bundle-ClassPath” header.

Example “build.gradle”


dependencies {
           
            compile  group: 'org.apache.poi', name: 'poi', version: '4.1.2'
            compile  group: 'org.apache.poi', name: 'poi-ooxml', version: '4.1.2'
}


 Add Jars in “includeresource” header in bnd.bnd file


-includeresource: \
META-INF/lib/poi-4.1.2.jar=poi-4.1.2.jar;lib:=true,\
META-INF/lib/poi-ooxml-4.1.2.jar=poi-ooxml-4.1.2.jar;lib:=true


META-INF/lib/poi-4.1.2.jar : will specify that jar will be copied to module META-INF/lib in the jar file.

poi-4.1.2.jar : It is actual jar file required by module. Name and version should match the dependency specified in “build.gradle” file.

we can also specify jar version regex pattern as follows


-includeresource: \
META-INF/lib/poi-4.1.2.jar=poi-[0-9]*.jar;lib:=true,\
META-INF/lib/poi-ooxml-4.1.2.jar=poi-ooxml-[0-9]*.jar;lib:=true


lib:=true : Will specify that jar references will be added to MANIFEST.MF “Bundle-ClassPath” header.


Option: 2

This option will directly add all jars as distributed packages in module and packages are specified in “Private-Package” header.

Example “build.gradle”


dependencies {
           
            compile  group: 'org.apache.poi', name: 'poi', version: '4.1.2'
            compile  group: 'org.apache.poi', name: 'poi-ooxml', version: '4.1.2'
}


Add Jars in include resources header in bnd.bnd file as follows


-includeresource: \
@poi-4.1.2.jar,\
@poi-ooxml-4.1.2.jar



Maven Liferay OSGi Module

Module Source


If you are developing Liferay OSGi Modules with MAVEN build tool, use pom.xml and bnd file to specify third party jars.

  1. Specify JAR as Maven dependency with provided scope
  2. Specify JAR information in “includeresource” header in bnd file.

Specify JAR as Maven dependency with provided scope

Example in pom.xml


<dependency>
       <groupId>org.apache.poi</groupId>
       <artifactId>poi</artifactId>
       <version>4.1.2</version>
       <scope>provided</scope>
</dependency>
<dependency>
       <groupId>org.apache.poi</groupId>
       <artifactId>poi-ooxml</artifactId>
       <version>4.1.2</version>
       <scope>provided</scope>
</dependency>


Specify JAR information in “includeresource” header in bnd file.

Option: 1

Add Jars in include resources header in module bnd.bnd file


-includeresource: \
META-INF/lib/poi-4.1.2.jar=poi-4.1.2.jar;lib:=true,\
META-INF/lib/poi-ooxml-4.1.2.jar=poi-ooxml-4.1.2.jar;lib:=true


META-INF/lib/poi-4.1.2.jar : will specify that jar will be copied to module META-INF/lib in the jar file package.

poi-4.1.2.jar : It is actual jar file required by module and name and version should match the dependency in specified in build.gradle file.

we can also specify jar version regex pattern as follows


-includeresource: \
META-INF/lib/poi-4.1.2.jar=poi-[0-9]*.jar;lib:=true,\
META-INF/lib/poi-ooxml-4.1.2.jar=poi-ooxml-[0-9]*.jar;lib:=true


lib:=true : Will specify that jar references will be added to MANIFEST.MF “Bundle-ClassPath” header.

Option: 2

This option will directly add all jars as distributed packages in module and packages are specified in “Private-Package” header.

Add Jars in include resources header in bnd.bnd file


-includeresource: \
@poi-4.1.2.jar,\
@poi-ooxml-4.1.2.jar


Important Note

When we add non OSGi third party jars we can expect “Unresolved requirement: Import-Package” error for specific packages and module might not deployed. These packages may not be used directly in the current Liferay OSGi module but we can see these errors.

Example


org.osgi.framework.BundleException: Could not resolve module: com.liferaysavvy.employee.portlet [1080]
  Unresolved requirement: Import-Package: com.graphbuilder.curve


Solution:

We can ignore packages using Import-Package header or we can add specified missing package jar as third party non OSGi jar.

Ignore Packages as follows.

Example


Import-Package: \
!com.graphbuilder.*,\
!com.github.luben.zstd.*,\
!com.github.luben.zstd.*,\
!com.microsoft.schemas.*,\
!net.sf.saxon.*,\
!org.apache.batik.*,\
!org.apache.jcp.xml.dsig.internal.*,\
!org.bouncycastle.asn1.*,\
!org.bouncycastle.*,\
!org.bouncycastle.cms.*,\
!org.brotli.dec.*,\
!org.etsi.uri.*,\
!org.openxmlformats.schemas.*,\
!org.tukaani.xz.*,\
!com.zaxxer.sparsebits.*,\
!org.apache.commons.codec.*,\
!org.apache.commons.collections4.*,\
!org.apache.commons.compress.*,\
!org.apache.commons.math3.*,\
!org.apache.xmlbeans.*,\
!org.w3.x2000.*,\
\
*


Don’t forget to add \ * end of configuration otherwise all Liferay default packages will be ignored in the “Import-Package” header in the jar file. It will lead to so many unresolved requirement errors.

Once modules deployed in Liferay OSGi module framework then you can add widget to the page.


Once portlet added in the console you can see that apache poi related code being executed.


Note:

The objective of code example is to understand the adding third party jars to OSGi module and its not real example to explain about apache poi.
Author

0 comments :

Post a Comment

Recent Posts

Recent Posts Widget

Popular Posts