After you write a module in Liferay Workspace, you can validate it before deployment to make sure of several things:
- Will my app deploy successfully?
- Will there be some sort of missing requirement?
- If there’s an issue, how do I diagnose it?
These are all common worries that can be frustrating.
Instead of deploying your app and checking for errors in the log, you can
validate your app before deployment. This is done by calling Liferay Workspace’s
resolve task, which validates your modules against a targeted platform.
You’ll cover the following topics in this section:
- Resolving your modules.
- Modifying the target platform’s capabilities.
- Including the resolver in your Gradle build.
Continue on to learn how this works.
You can resolve your modules before deployment. This can be done by calling the
resolve Gradle task provided by Liferay Workspace.
This task gathers all the capabilities provided by
- the specified version of Liferay DXP (i.e., targeted platform)
- the current workspace’s modules
Some capabilities/information gathered by the
resolve task that are validated
- declared required capabilities
- module versions
- package imports/use constraints
- service references
It also computes a list of run requirements for your project. Then it compares the current project’s requirements against the gathered capabilities. If your project requires something not available in the gathered list of capabilities, the task fails.
The task can only validate OSGi modules. It does not work with WAR-style projects, themes, or npm portlets.
resolve task can automatically gather the available capabilities from your
workspace, but you must specify this for your targeted Liferay DXP version. To do
this, open your workspace’s
gradle.properties file and set the
liferay.workspace.target.platform.version property to the version you want to
target. For example,
If you’re using Liferay DXP, you can set the property like this:
The versions following a GA1 release of DXP follow fix pack versions (e.g.,
Setting the target platform property provides a static distro JAR for the specified version of Liferay DXP, which contains all the metadata (i.e., capabilities, packages, versions, etc.) running in that version. The distro JAR is a complete snapshot of everything provided in the OSGi runtime; this serves as the target platform’s list of capabilities that your modules are validated against.
You can now validate your module projects before deploying them! If the resolver
throws errors, see the article on
how to resolve common output errors reported by the
Sometimes, you must modify the
resolve task’s default behavior to successfully
validate your app. See the next section for more information.
In a perfect world, everything the
resolve task gathers and checks against
would work during your development process. Unfortunately, there are exceptions
that may force you to modify the default functionality of the
There are two scenarios you may run into during development that require a modification for your project to pass the resolver check.
- You’re depending on a third party library that is not available in the targeted Liferay DXP instance or the current workspace.
- You’re depending on a customized distribution of Liferay DXP.
You’ll explore these use cases next.
resolve task, by default, gathers all of Liferay DXP’s capabilities and the
capabilities of your workspace’s modules. What if, however, your module depends
on a third party project that is not included in either space (e.g.,
Google Guava)?. The
task fails by default if your project depends on this project type. You
probably plan to have this project deployed and available at runtime, so it’s
not a concern, but the resolver doesn’t know that; you must customize the
resolver to bypass this.
There are three ways you can do this:
- Embed the third party library in your module
- Add the third party library’s capabilities to the current static set of resolver capabilities
- Skip the resolving process for your module
For help resolving third party dependency errors, see the Resolving Third Party Library Package Dependencies tutorial.
There are times when manually specifying your project’s list of dependent JARs does not suffice. If your app requires a customized Liferay DXP instance to run, you must regenerate the target platform’s default list of capabilities with an updated list. Two examples of a customized Liferay DXP instance are described below:
Example 1: Leveraging an External Feature
There are many external features/frameworks available that are not included in
the downloadable bundle by default. After deploying a feature/framework, it’s
available for your module projects to leverage. When validating your app,
resolve task does not have access to external capabilities not
included by default. For example, Audience Targeting is an example of this type
of external framework. If you’re creating a Liferay Audience Targeting rule that
depends on the Audience Targeting framework, you can’t easily provide a slew of
JARs for your module. In this case, you should install the platform your code
depends on and regenerate an updated list of capabilities that your Liferay DXP
Example 2: Leveraging a Customized Core Feature
You can extend Liferay DXP’s core features to provide a customized experience for
your intended audience. Once deployed, you can assume these customizations are
present and build other things on top of them. The new capabilities resulting
from your customizations are not available, however, in the target platform’s
default list of capabilities. Therefore, when your application relies on
non-default capabilities, it fails during the
resolve task. To get around
this, you must regenerate a new list of capabilities that your customized
Liferay DXP instance provides.
To regenerate the target platform’s capabilities (distro JAR) based on the current workspace’s Liferay DXP instance, follow the Depending on a Customized Distribution of Liferay DXP article.
By default, Liferay Workspace provides the
resolve task as an independent
executable. It’s provided by the
Gradle plugin and is not integrated in any other Gradle processes. This gives
you control over your Gradle build without imposing strategies you may not want
included in your default build process.
With that said, the
resolve task can be useful to include in your build
process if you want to check for errors in your module projects before
deployment. Instead of resolving your projects separately from your standard
build, you can build and resolve them all in one shot.
In Liferay Workspace, the recommended path for doing this is adding it to the
check Gradle task. The
check task is provided by default in a
workspace by the
plugin. Adding the
resolve task to the
check lifecycle task also promotes
resolve task to run for CI and other test tools that typically run the
check task for verification. Of course, Gradle’s
build task also depends on
check task, so you can run
gradlew build and run the resolver too.
You can learn how to include the resolver in your Gradle build by visiting this article.
Continue on for various step-by-step instructions for configuring/manipulating the resolver task.