Importing Packages

Plugins often must use Java classes from packages outside of themselves. Another OSGi bundle (a module or an OSGi Web Application Bundle) in the OSGi framework must export a package for your plugin to import it.

When an OSGi bundle (bundle) is set up to import packages, the OSGi framework finds other registered bundles that export the needed packages and wires them to the importing bundle. At run time, the importing bundle gets the class from the wired bundle that exports the class’s package.

For this to happen, a bundle’s META-INF/MANIFEST.MF file must specify the Import-Package OSGi manifest header with a comma-separated list of the Java packages it needs. For example, if a bundle needs classes from the javax.portlet and com.liferay.portal.kernel.util packages, it must specify them like so:

Import-Package: javax.portlet,com.liferay.portal.kernel.util,*

The * character represents all packages that the module refers to explicitly. Bnd detects the referenced packages.

Import packages must sometimes be specified manually, but not always. Conveniently, Liferay DXP project templates and tools automatically detect the packages a bundle uses and add them to the package imports in the bundle’s manifest. Here are the different package import scenarios:

Let’s explore how package imports are specified in these scenarios.

Automatic Package Import Generation

Gradle and Maven module projects created using Blade CLI, Liferay’s Maven archetypes, or Liferay Dev Studio DXP use bnd. On building such a project’s module JAR, bnd detects the packages the module uses and generates a META-INF/MANIFEST.MF file whose Import-Package header specifies the packages.

For example, suppose you’re developing a Liferay module using Maven or Gradle. In most cases, you specify your module’s dependencies in your pom.xml or build.gradle file. At build time, the Maven or Gradle module plugin reads your pom.xml or build.gradle file and bnd adds the required Import-Package headers to your module JAR’s META-INF/MANIFEST.MF.

Here’s an example dependencies section from a module’s build.gradle file:

dependencies {
    compileOnly group: "com.liferay.portal", name: "com.liferay.portal.kernel", version: "2.0.0"
    compileOnly group: "javax.portlet", name: "portlet-api", version: "2.0"
    compileOnly group: "org.osgi", name: "org.osgi.service.component.annotations", version: "1.3.0"
}

And here’s the Import-Package header that’s generated in the module JAR’s META-INF/MANIFEST.MF file:

Import-Package: com.liferay.portal.kernel.portlet.bridges.mvc;version=
"[1.0,2)",com.liferay.portal.kernel.util;version="[7.0,8)",javax.nami
ng,javax.portlet;version="[2.0,3)",javax.servlet,javax.servlet.http,j
avax.sql

Note that your build file need only specify artifact dependencies. bnd examines your module’s class path to determine which packages from those artifacts contain classes your application uses and imports the packages. The examination includes all classes found in the class path–even those from embedded third party library JARs.

Regarding classes used by a plugin WAR, Liferay’s WAB Generator detects their use in the WAR’s JSPs, descriptor files, and classes (in WEB-INF/classes and embedded JARs). The WAB Generator searches the web.xml, liferay-web.xml, portlet.xml, liferay-portlet.xml, and liferay-hook.xml descriptor files. It adds package imports for classes that are neither found in the plugin’s WEB-INF/classes folder nor in its embedded JARs.

Manually Adding Package Imports

The WAB Generator and bnd don’t add package imports for classes referenced in these places:

  • Unrecognized descriptor file
  • Custom or unrecognized descriptor element or attribute
  • Reflection code
  • Class loader code

In such cases, you must manually determine these packages and specify an Import-Package OSGi header that includes these packages and the packages that Bnd detects automatically. The Import-Package header belongs in the location appropriate to your project type:

Project typeImport-Package header location
Module (uses bnd)[project]/bnd.bnd
Module (doesn’t use bnd)[module JAR]/META-INF/MANIFEST.MF
Traditional Liferay plugin WARWEB-INF/liferay-plugin-package.properties

Here’s an example of adding a package called com.liferay.docs.foo to the list of referenced packages that Bnd detects automatically:

Import-Package:\
    com.liferay.docs.foo,\
    *

Please see the Import-Package header documentation for more information.

Congratulations! Now you can import all kinds of packages for your modules and plugins to use.

Configuring Dependencies

Deploying WARs (WAB Generator)

Project Templates

Liferay’s Maven Archetypes

Blade CLI

Liferay Dev Studio DXP

« Using the Felix Gogo ShellExporting Packages »
この記事は役に立ちましたか?
0人中0人がこの記事が役に立ったと言っています