Blogs

Blogs

Never get into trouble with 'Unresolved requirement' again

       If you are a new to liferay 7.x platform since liferay had migrate to OSGi platform, you must have meet the error Unresolved requirement: Import-Package  when deploying your bundles, i have a easy solution for you —— 'Take a look at your bundle's MANIFEST.MF'.

      When you deploying your bundle to liferay portal, the OSGi container will resolve your bundle's MANIFEST.MF that contains all the dependencies relationship. If your MANIFEST file have declare a import package that doesn't exist in OSGi runtime or can't be found by OSGi classloader, you will get this ` Unresolved requirement ` message. I have some use cases for you.

1. If you want to import a third-party dependency, you may consider compileOnly  or compile  in the first time. But i'm sorry that it only help you to pass the java compile time, however, OSGi knows nothing about to find your dependency during it's runtime. Then we introduce compileInclude  configuration in gradle plugin.

it will help you to package the `compileInclude` dependencies into the jar's lib   folder and set a Bundle-ClassPath  property to MANIFEST, then the OSGi classloader can locate it.

2. You may encounter some weird problems when using some specific dependencies.

dependencies {

      compileInclude group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.6'

}

But you will get a error message :

Unresolved requirement: Import-Package: org.apache.avalon.framework.logger

Why it would happen since I never introduce this? Remember the solution i said? Take a look at your jar's MANIFEST.MF, you will find that it actually contains the import-package org.apache.avalon.framework.logger . It was introduced because the http client dependency that has import this package thus the bnd tool(The OSGi bundle builder) will automatic add this package. so you can exclude this import package in bnd.bnd.

Import-Package: \

  !*avalon*,\

  \

  *

3.The Unresolved import package also could happen on when you haven't pulling third-party dependencies that i met before. If you are developing a fragment bundle(such as  com.liferay.portal.search.web  ) to override the liferay bundle, and the file /META-INF/resources/custom/facet/view.jsp   to modify, although you haven' t modify this file , you can still get the unresolved import error

`Unresolved requirement: Import-Package: com.liferay.portal.search.web.internal.custom.facet.display.context`

this package is a internal package that means it don't want to be exposed to outside, and your fragment just want to import that. so your can safely exclude this import package in bnd.bnd, and the MANIFEST won't contain this import declaration. Will this result in a NoClassDefFoundError  during runtime? No, it won't, because the host bundle and the fragment bundle shared the same class loader to load this package's class.

Below is the order about OSGi load class, I hope it could help you to understand the resolving process: