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

Saturday, February 29, 2020

Apache Gogo Shell Commands Description


lb
Display list of bundles installed in OSGi module framework

lb | grep <BUNDLE_MATCH_PATTERN>
List of bundles with filter using grep command and you can pass any string or valid regex pattern.

bundle <BUNDLE_ID>
Print specific bundle information. It required bundle Id as parameter

headers <BUNDLE_ID>
Print all OSGi headers which is used by specified bundle. These headers are in MANIFEST.MF file. It is required bundle Id as parameter.

install [URI_JAR_FILE_PATH]
Install bundle into OSGi container and we need to specify the valid URI path.

start [BUNDLE_ID]
Command will start bundle and it is required bundle Id.

stop [BUNDLE_ID]
Command will stop bundle and it is required bundle Id.

uninstall [BUNDLE_ID]
Uninstall bundle and it required bundle Id.

inspect requirement service [BUNDLE_ID]
List all services required by bundle. Require-Capability header is in MANIFEST.MF file is relevant to this command.

inspect capability service [BUNDLE_ID]
List all services provided by bundle. Provide-Capability header is in MANIFEST.MF file is related to this command.

diag [BUNDLE_ID]
Command will print unsatisfied constraints to specific bundle and its required bundle Id.

upgrade:check
Command will display all Upgrade Step Process Steps registered in the registry.

system:check
Command will show all unsatisfied components list along with Gogo shell commands to troubleshoot in detail. It will run Declarative Service Soft Circular Dependency Checker, Declarative Service Unsatisfied Component Checker, Spring Extender Unavailable Component Checker

history
history will print all commands used in the current session. It is similar to Unix/Linux history command.

help
It will show all available commands and its description.

services
Command will print all registered service components available in the OSGi module framework.

services grep [SEARCH-PATTERN]
Command will print all registered service components available in the OSGi module framework with filter. It will narrow down the list.

ds:unsatisfied
Command will display all unsatisfied service component list in the OSGi module framework.

ds:unsatisfied [BUNDLE_ID]
Command will display unsatisfied service components to specified bundle. It’s required bundle Id

scr:info [COMPONENT_ID]
Command will print detailed information of given component. It required the component Id and we can get component Id when we use services/ ds:unsatisfied commands.

scr:list
It will display all components registered in service registry.

scr:list | grep [SEARCH-PATTERN]
It will display matching components registered in service registry.

dm
List all dependency manager components and these are mostly service builder service components from Liferay OSGi Module Framework.

dm OR grep [SEARCH-PATTERN]
List all matching dependency manager components and these are mostly service builder service components from Liferay OSGi Module Framework.

dm cp OR  dm compact
Display components in compact from.

dm nd OR dm nodeps
Command will display only components and it is hiding dependencies of the component.

dm na OR dm notavail
It will print only not available dependency components. It is very useful when we troubleshoot unsatisfied service builder components.

dm wtf
Detects where are the root failures for components. This is also most useful command to troubleshoot service builder components

Example Usage of Commands

lb

lb | grep student

bundle 1076

headers 1076

install "file:C://Liferay/Liferay7.2/student-web/target/student-web-1.0.0.jar"

start 1076

stop 1076

uninstall 1076

inspect requirement service 1076

inspect capability service 1076

diag 1076

upgrade:check
system:check
history
help

services

services | grep student

ds:unsatisfied

ds:unsatisfied 1075

scr:info 4884

scr:list

scr:list | grep student

dm

dm | grep student

dm cp

dm nd

dm na

dm wtf

Author

Useful Apache Gogo Shell Commands in Liferay 7.2/DXP


Apache Gogo Shell is command line interface (CLI) to interact with OSGi module framework or OSGi container.

Apache Gogo shell is very useful in trouble shooting of module issues, getting module information and perform certain action like install, active and de-active OSGi bundles.

Liferay is already using Apache Gogo Shell and when we start Liferay 7.2/DXP portal, it will start automatically and we can use different ways to access Apache Gogo Shell in Liferay Portal Environment.


We can categorize Gogo shell commands in the following types.

Basic Commands
Declarative Services (DS) | Service Component Registry Commands (SCR) Commands
Dependency Management (DM) Commands

Basic Commands

Its regular usage commands to get bundles/module information like list bundles and its status.
Following are list of useful basic commands.


lb
lb | grep <BUNDLE_MATCH_PATTERN>
bundle <BUNDLE_ID>
headers <BUNDLE_ID>
install [URI_JAR_FILE_PATH]
start [BUNDLE_ID]
stop [BUNDLE_ID]
uninstall [BUNDLE_ID]
inspect requirement service [BUNDLE_ID]
inspect capability service [BUNDLE_ID]
diag [BUNDLE_ID]
upgrade:check
system:check
history
help

Example Usage


lb
lb | grep student
bundle 1076
headers 1076
install "file:C://Liferay/Liferay7.2/student-web/target/student-web-1.0.0.jar"
start 1076
stop 1076
uninstall 1076
inspect requirement service 1076
inspect capability service 1076
diag 1076
upgrade:check
system:check
history
help


Identify Bundle ID

Use lb command in the Gogo shell it will display the list of bundles installed in the OSGi modules framework. In the console view first column represent the BUNDLE ID.

Example


Declarative Services (DS) | Service Component Registry Commands (SCR)

Liferay module framework uses the OSGi Declarative Services/Service Component Registry to manage module components and its services references. Gogo shell leverage the Service Component Registry and Declarative Services. We can access services information using Gogo shell commands. 
In Liferay 7.2/DXP most of modules are using DS/SCR framework. Only service builder components are using the Apache Felix Dependency Management Framework to register and manage service components.

If you see any @Component or @Reference annotations in the java class, it implies that module components are using the Declarative Services/Service Component Registry Framework.

The following are some of useful Gogo Shell commands to insect components and its references.

services
services grep [SEARCH-PATTERN]
ds:unsatisfied
ds:unsatisfied [BUNDLE_ID]
scr:info [COMPONENT_ID]
scr:list
scr:list | grep [SEARCH-PATTERN]


Example Usage


services
services | grep student
ds:unsatisfied
ds:unsatisfied 1075
scr:info 4884
scr:list
scr:list | grep student


Identify COMPONENT ID

Use services/ ds:unsatisfied go shell commands and it will display component information and its ID.

Example 1


Example 2


Dependency Management (DM) Commands

Liferay Service Builder is using Apache Felix Dependency Management framework to manage components and its dependencies. Apache Gogo Shell leverage the Dependency Management framework and have set of predefined commands to provide more details of service components.
These commands are very useful when we trouble shoot about unsatisfied services in the registry.

The following are some of useful Gogo Shell commands related to Dependency Management

dm
dm | grep [SEARCH-PATTERN]
dm cp
dm nd
dm na
dm wtf


OR

dm
dm | grep [SEARCH-PATTERN]
dm compact
dm nodeps
dm notavail
dm wtf

Example Usage

dm
dm | grep student
dm cp
dm nd
dm na
dm wtf


Example usage screen



Reference


Author


Recent Posts

Recent Posts Widget

Popular Posts