Deploying WARs (WAB Generator)
You can create applications as Java EE-style Web Application ARchive (WAR) artifacts or as Java ARchive (JAR) OSGi bundle artifacts. Bean Portlets, PortletMVC4Spring Portlets, and JSF Portlets must be packaged as WARs because their frameworks 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 supports the OSGi Web Application Bundle (WAB) standard for deployment of Java EE style WARs. 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 project source has a WAR layout, the artifact filename may end with either the .jar
or .war
extension.
How the WAB Generator Transforms WARs
Liferay only supports the use of WABs that have been auto-generated by the WAB Generator. The WAB Generator transforms a traditional WAR-style plugin into a WAB during deployment. 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 the 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
OSGi header in the WAB’s META-INF/MANIFEST.MF
file.
To import a package that is referenced only 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 that header’s list of values:
- Unrecognized descriptor file
- Custom or unrecognized descriptor element or attribute
- Reflection code
- Class loader code
WAR versus WAB Structure
The WAB folder structure and WAR folder structure differ. Consider the following folder structure of a WAR-style portlet.
WAR
my-war-portlet
src
main
java
webapp
WEB-INF
classes
lib
resources
views
liferay-display.xml
liferay-plugin-package.properties
liferay-portlet.xml
portlet.xml
web.xml
When a WAR-style portlet is deployed to Liferay and processed by the WAB Generator, the portlet’s folder structure is transformed.
WAB
my-war-portlet-that-is-now-a-wab
META-INF
MANIFEST.MF
WEB-INF
classes
lib
resources
views
liferay-display.xml
liferay-plugin-package.properties
liferay-portlet.xml
portlet.xml
web.xml
The major difference is the addition of the META-INF/MANIFEST.MF
file. The WAB Generator automatically generates an OSGi-ready manifest file. If you want to affect the content of the manifest file, you can place Bnd directives and OSGi headers directly into your plugin’s liferay-plugin-package.properties
file.
A generated WAB cannot use a manually added bnd.bnd
file or a build-time plugin (e.g., bnd-maven-plugin
).
Deploying a WAR
To deploy a WAB based on your WAR plugin, copy your WAR plugin to your Liferay instance’s deploy/
folder in your [Liferay Home]
. The WAB is created in the directory determined by the module.framework.war.dir
property (osgi/war
by default).
Saving the Generated WAB
Optionally, save the WAB to a local folder. This gives you the opportunity to inspect the generated WAB. To store generated WABs, add the following portal properties to a [Liferay Home]/portal-ext.properties
file. Then restart the Liferay server:
module.framework.web.generator.generated.wabs.store=true
module.framework.web.generator.generated.wabs.store.dir=${module.framework.base.dir}/wabs
These properties instruct the WAB generator to store generated WABs in your installation’s osgi/wabs/
folder. The generated WABs have the same structure as the example WAB structure above. The Module Framework Web Application Bundles properties section explains more details.
Destroying a WAB
Liferay destroys all WABs automatically when the portal or the OSGi framework are shut down.
To destroy a WAB that hasn’t been deployed, delete the file in the deploy/
folder. To avoid issues, Liferay waits 60 seconds to destroy the WAB if it is being deployed. You can change this timeout in Control Panel → Configuration → System Settings → Module Container → WAB Extender. Set the timeout in milliseconds (e.g. 120000
).
To destroy a WAB that’s already been deployed, delete the file in the folder where your Liferay instance stores WARs (this is set by the module.framework.war.dir
property).