Showing posts with label Import-Package Error. Show all posts
Showing posts with label Import-Package Error. Show all posts

Thursday, March 12, 2020

Unrelated packages Unresolved requirement Import-Package Error in Liferay OSGi Module Framework

When we started using third-party non-OSGi jars, we can see Unresolved requirement: Import-Package” error for the packages but those packages we may not use directly in the current developing module (unrelated packages). This is due to third-party jar transitive dependencies.

If we use compileInclude scope for third-party dependencies for gradle build type module then it will add all its transitive dependencies packages as part of “Import-Package” list during build process.

Example Error


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 in module bnd.bnd file 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.*,\
\
*

If we override the “Import-Package” header in the bnd.bnd file, we should add \ * end of list otherwise it will ignore all Liferay default packages during the build process.  Don’t forget this and if you missed, it will lead to so many unresolved requirement errors.

Before ignoring packages, we must check whether package is really can be ignorable or not. If the package is really unrelated to module then we can ignore it but we need to verify thoroughly after deployment.  If the non-OSGi third party jar and its dependencies is required by module then add it to the module.


Unresolved Import-Package can be only identified after module deployment and it will display only one Unresolved Import-Package for each time and it wont show all at once. Assume if we have 10 Unresolved Import-Packages then we have to deploy module for 10 times to know these 10 Unresolved Import-Packages.  This is very pain point for developer for initial phase of module development. This scenario can be experienced when we are trying to use third party non-OSGi jars in the module.

We can see these Unresolved Import-Package error in console during the deployment of module or we can use Gogo shell to see the error and package.

You can use following Gogo shell command to know the reason


diag [BUNDLE_ID]





Lets take the example, if you are trying add apache poi libraries to the module then we may have to ignore many unrelated packages in the Import-Package of bnd.bnd file. To identify these unrelated packages, we may have to build and deploy modules for several times. These packages we may not use directly in the module.

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.*,\
\
*


Tip to Identify Unrelated/Ignorable packages

  1. Add your third party-non OSGi jars to module.
  2. Build the module.
  3. Open MANIFEST.MF file and extract Import-Package header list.
  4. Identify the all unrelated packages and ignore it in the bnd.bnd file.

Add your third party-non OSGi jars to module

If you think that your module required third-party non-OSGi jars and add it the module.


Take the example of apache poi libraries.

Build the module

Build the module using your build tool MAVEN or GRADLE

Open MANIFEST.MF file and extract Import-Package header list

Once module build is success it will generate jar file and output files in build directory.

MAVEN we can see these generated files in Target directory in the parent directory of module.


Gradle we can see these generated files in build directory in the parent directory of module




Open MANIFEST.MF file after build. You can use JD-GUI java de-compiler to see files in jar file.



If you are using MAVEN you can see MANIFEST file in classes directory. Extract the Import-Package header package list in editor


Identify the all unrelated packages and ignore it in the bnd.bnd file.

Identify all the unrelated packages to current module from extracted text. Don’t add any Liferay or module specific packages in the ignore list.

Add packages to module bnd.bnd file as ignorable packages. We may see following ignorable packages when we are trying to add apache poi libraries.

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.*,\
\
*


This may help you to find all ignorable packages at one time and can avoid number of build deployments to find Unresolved Import-Packages. 

Wednesday, March 11, 2020

Unresolved requirement Import-Package Error in Liferay OSGi Module Framework


When we are developing Liferay OSGi modules, we can see “Unresolved requirement Import-Package Error” while deploying modules. This is very common error we can encounter in deployment of modules and finally module will not be in active state but it’s in installed state.


org.osgi.framework.BundleException: Could not resolve module: com.liferaysavvy.employee.portlet [3218]_  Unresolved requirement: Import-Package: org.apache.poi.ss.usermodel_ [Sanitized]
       at org.eclipse.osgi.container.Module.start(Module.java:444)
       at org.eclipse.osgi.internal.framework.EquinoxBundle.start(EquinoxBundle.java:428)
       at org.apache.felix.fileinstall.internal.DirectoryWatcher.startBundle(DirectoryWatcher.java:1264)
       at org.apache.felix.fileinstall.internal.DirectoryWatcher.startBundles(DirectoryWatcher.java:1237)
       at org.apache.felix.fileinstall.internal.DirectoryWatcher.doProcess(DirectoryWatcher.java:520)
       at org.apache.felix.fileinstall.internal.DirectoryWatcher.process(DirectoryWatcher.java:365)
       at org.apache.felix.fileinstall.internal.DirectoryWatcher.run(DirectoryWatcher.java:316)



You can use following Gogo shell command to know the reason

diag [BUNDLE_ID]




Reason for the Error

The package that Liferay OSGi Module used in “Import-Package” list was not exported by any of the other module in the Liferay OSGi module framework.

The following are two fundamental things to understand above error.

  1. When you use any package in module “Import-Package” list, specified package must be Exported by other module in Liferay OSGi module framework.
  2. If the other module was not exported the package already then it should be in module “Private-Package” list.

When you use any package in module “Import-Package” list, specified package must be Exported by other module in Liferay OSGi module framework.

Usually we use “Import-Package” header in MANIFEST file list all packages that required by module. Liferay OSGi module uses the bnd.bnd file to specify the MANIFEST headers and bnd tools will finally update the configuration in module MANIFEST.MF file in the build process.

Even if we are not specifying any packages explicitly in the “Import-Package” list in bnd.bnd file, bnd tools will add packages for “Import-Package” header during the build time. Bnd tools are very smart enough to find all packages that module uses will be added in “Import-Package” header. You can notice it in jar file MANIFEST.MF

Usually exported packages will be defined in “Export-PackageMANIFEST.MF header. If its custom Liferay OSGi module, Export-Package header can be used in bnd.bnd file.

Usually Packages will be exported at different level in Liferay OSGi Module Framework.

  1. Global Packages exported by Liferay Module Framework
  2. Liferay Portal Bootstrap module exported system extra packages
  3. Developer Developed custom OSGi modules.

To understand Global Exported and Liferay Bootstrap Exported packages follow the below blog.


Developer Developed custom OSGi modules

If the package belongs to one of your custom Liferay OSGi module then use “Export-Package” header in module bnd.bnd file.

Example: bnd.bnd file


Export-Package: com.liferaysavvy.employee.portlet.constants


If any package the module is using or listed in “Import-Package” list was exported by any one of above procedure then package must be resolved.

If the other module was not exported that package already then it should be in module “Private-Package” list.

If the module required package was not exported already in the above procedure then we can see same error. When we use some third-party jars in the modules then we can expect the same error.

Solution: 1

If the module required package is from third party library then we need to find OSGi compliance version of same jar and deploy in Liferay Module Framework. Newer version of third-party libraries are OSGi compliance.

How to identify the JAR is OSGi compliance?

Check MANIFEST.MF file with OSGi headers.

Example: latest google gson-2.8.6.jar is OSGi compliance


How to deploy OSGi compliance third-party library into OSGi module framework?

Simply place the jar file in Liferay portal bundle “osgi/module directory. In the logs you can see Module STARTED statement.  

Solution: 2

If the jar was not found as OSGi compliance jar then use includeresource option. Includeresource option will add jar to module lib directory and add packages in the private package list.

Follow the below blog to add third party non-OSGi jars to Liferay OSGi module.


Recent Posts

Recent Posts Widget

Popular Posts