Developers creating applications for Liferay DXP 7.0 can choose to create them as
Java EE-style Web Application ARchive (WAR) artifacts or as Java ARchive (JAR)
OSGi bundle artifacts. Some plugin developers, however, don’t have that
flexibility. Portlets like Spring MVC and JSF must be packaged as WAR artifacts
because their frameworks are designed for Java EE. Therefore, they expect a WAR
layout and require Java EE resources such as the WEB-INF/web.xml
descriptor.
Liferay provides a way for these WAR-styled plugins to be deployed and treated like OSGi modules by Liferay’s OSGi runtime. They can be converted to WABs.
Liferay DXP 7.0 supports the OSGi Web Application Bundle (WAB) standard for
deployment of Java EE style WARs. Simply put, a WAB is an archive that has a WAR
layout and contains a META-INF/MANIFEST.MF
file with the Bundle-SymbolicName
OSGi directive. A WAB is an OSGi bundle. Although the source of the project has
a WAR layout, the artifact filename may end with either the .jar
or .war
extension.
Liferay only supports the use of WABs that have been auto-generated by the WAB Generator. The WAB Generator transforms a general WAR-style plugin into a WAB during its deployment process. So what exactly does the WAB Generator do to a WAR file to transform it into a WAB?
The WAB Generator detects packages referenced in a plugin WAR’s JSPs, descriptor
files, and classes (in WEB-INF/classes
and embedded JARs). The descriptor
files include web.xml
, liferay-web.xml
, portlet.xml
,
liferay-portlet.xml
, and liferay-hook.xml
. The WAB Generator verifies
whether the detected packages are in the plugin’s WEB-INF/classes
folder or in
an embedded JAR in the WEB-INF/lib
folder. Packages that aren’t found in
either location are added to an Import-Package
header in the WAB’s
META-INF/MANIFEST.MF
file.
To import a package that is only referenced in the following types of locations,
you must add an Import-Package
OSGi header to the plugin’s
WEB-INF/liferay-plugin-package.properties
file and add the package to the
header’s list of values.
- Unrecognized descriptor file
- Custom or unrecognized descriptor element or attribute
- Reflection code
- Class loader code
The WAB folder structure and WAR folder structure differ. Consider the following folder structure of a WAR-style portlet:
- my-war-portlet
- src
- main
- java
- webapp
- WEB-INF
- classes
- lib
- resources
- views
- faces-config.xml
- liferay-display.xml
- liferay-plugin-package.properties
- liferay-portlet.xml
- portlet.xml
- web.xml
- WEB-INF
- main
- src
When a WAR-style portlet is deployed to Liferay DXP and processed by the WAB Generator, the portlet’s folder structure is transformed to something like this
- my-war-portlet-that-is-now-a-wab
- META-INF
- MANIFEST.MF
- WEB-INF
- classes
- lib
- resources
- views
- faces-config.xml
- liferay-display.xml
- liferay-plugin-package.properties
- liferay-portlet.xml
- portlet.xml
- web.xml
- META-INF
The major difference is the addition of the META-INF/MANIFEST.MF
file. The WAB
Generator automatically generates an OSGi-ready MANIFEST.MF
file. If you want
to affect the content of the manifest file, you can place BND directives and
OSGi headers directly into the liferay-plugin-package.properties
file.
A bnd.bnd
and/or a build-time plugin (e.g., bnd-maven-plugin
) should not be
provided for your WAR plugin, because the generated WAB cannot make use of them.
Do you want to try this out for yourself? Follow the steps below to see the WAB Generator in action.
-
Create a WAR-style plugin that follows a similar structure to the one outlined above. You can download an example WAR-style portlet here, for demonstration.
-
Open your Liferay DXP instance in a file explorer and add a
portal-ext.properties
file with the following properties:module.framework.web.generator.generated.wabs.store=true module.framework.web.generator.generated.wabs.store.dir=${module.framework.base.dir}/wabs
These properties store your generated WAB into your Liferay DXP instance’s
osgi/wabs
folder. You can learn more about these properties in the Module Framework Web Application Bundles properties section. Restart Liferay DXP for these changes to be recognized. -
Copy your WAR plugin in your Liferay DXP instance’s
deploy
folder. -
Navigate to your Liferay DXP instance’s
osgi/wabs
folder and inspect the generated WAB.
Awesome! You’ve seen the WAB Generator in action!