Deploy CE Clustering from Subrepositories

About one month ago, Liferay posted an announcement which talked about how to deploy the New Clustering Code for Liferay Portal Community.

One of the first steps documented in this announcement was to clone the liferay-portal repository. As mentioned in a previous blog post, Liferay from Source, while this sounds like it shouldn't be a big deal, the large size of the liferay-portal repository makes this first step far from trivial from a time perspective. Additionally, the announcement also tells you to run ant all, which is also far from trivial from a time perspective.

So you might be wondering, "Is it possible to deploy the clustering code without cloning that gigantic repository and running ant all?"

Yes, there's one way that's a little bit more complex, but ultimately much faster than cloning the entire liferay-portal repository: deploy the clustering code from subrepositories. Doing so provides another way to maintain any customizations to the clustering code by allowing collaborators to fork a much smaller repository.

After reading this post, you'll hopefully understand a little bit more about Liferay's repository layout and you'll hopefully have a better sense of how you can make small-scale changes to Liferay for your own personal purposes.

With that being said, this process is admittedly both slower and more complex than if you were to make use of changes bundled as a Marketplace application (as others are planning here) or if someone were to build the JARs for you and install them for you if you were to run docker-compose (as others have described here), so it might only be of interest to those who are building Liferay from source.

Step 1: Locate Subrepositories

Our first step is to locate what we're being told to deploy from liferay-portal and use that to identify which subrepositories we need to clone. We can do that by looking at the commands that are provided in the announcement.

cd modules
../gradlew :apps:foundation:portal:portal-cluster-multiple:deploy
../gradlew :apps:foundation:portal-cache:portal-cache-ehcache-multiple:deploy
../gradlew :apps:foundation:portal-scheduler:portal-scheduler-multiple:deploy

Essentially, the modules folder in the Liferay source is the root of Gradle multi-project build. As noted in the Gradle documentation, "The path of a task is simply its project path plus the task name." So in this case, we can see that we are executing the deploy task for each of the following projects:

  • :apps:foundation:portal:portal-cluster-multiple
  • :apps:foundation:portal-cache:portal-cache-ehcache-multiple
  • :apps:foundation:portal-scheduler:portal-scheduler-multiple

If you replace the colons with slashes, each of these project paths give you the actual file path to the Gradle projects:

Now that we have the project paths, the next step is to find the subrepository corresponding to that Gradle project. To identify that subrepository, you check each parent folder until you locate a .gitrepo file, which is essentially a metadata file that describes the root of a subrepository. These are the .gitrepo files for the Gradle projects we need to deploy.

If you look inside the .gitrepo file, you will find a remote field, which designates the repository we need to clone if you wish to have the subrepository corresponding to that folder in liferay-portal. Based on that, these are the commands we'd run in order to clone just the repositories we need to deploy clustering:

git clone git@github.com:liferay/com-liferay-portal.git
git clone git@github.com:liferay/com-liferay-portal-cache.git
git clone git@github.com:liferay/com-liferay-portal-scheduler.git

Step 2: Locate the Release Commit

Now that you have the subrepository, the next step is to decide whether you want to deploy the latest 7.0.x code or deploy the code at the time of the 7.0.4 GA5 release. Regardless of which route you choose, you'll need to make sure that you have the 7.0.x branch, since you will either checkout the branch itself or you will checkout a commit that only exists in that branch.

for folder in com-liferay-portal com-liferay-portal-cache com-liferay-portal-scheduler; do
    cd $folder
    git fetch origin 7.0.x:7.0.x
    git checkout 7.0.x
    cd ..
done

Liferay's GA releases aren't tagged in subrepositories, and so you'll need to find a different frame of reference. Luckily, if you look inside the .gitrepo file, you will find a commit field, which designates the commit in the subrepository which matches up against the current state within liferay-portal. Because all of the URLs we've been using so far in the liferay-portal repository refer directly to the 7.0.4-ga5 tag, this means that the commit field corresponds to the subrepository commit for the release. Therefore, you can navigate into each folder and checkout the correct commit. Assuming you're using the GA5, you would use these commands:

cd com-liferay-portal
git checkout ae0c594e47b3728d95340e4eddf1f5836b56f38c
cd -

cd com-liferay-portal-cache
git checkout 034a3671f9bded7c029a54488ef14d290754f2f2
cd -

cd com-liferay-portal-scheduler
git checkout 3de4a3de6c94337257994c8d32737ccbcd88b374
cd -

Step 3: Prepare Gradle Wrapper

At this point, you'll want to get a copy of the Gradle wrapper. Some repositories (particularly those that are already in pull mode) already have a Gradle wrapper committed to version control. However, this is not true for any of the clustering modules (at least, not at the time of this writing).

The version of Gradle used by Liferay at the specific tag will be documented in gradle-wrapper.properties in the portal source, and you can use Blade in order to retrieve it. In this case, Liferay uses Gradle 3.3, and we can acquire the proper Gradle wrapper by using blade init to initializing a Blade workspace (which will contain a Gradle wrapper), move it to the shared parent folder for all subrepositories, and reset the version to 3.3.

mkdir blade-temp
cd blade-temp
blade init

mv gradle ..
mv gradlew ..
mv gradlew.bat ..

cd -
rm -rf blade-temp

./gradlew wrapper --gradle-version=3.3

Step 4: Configure Liferay Home

Now, all we have to do is configure the Liferay module deployment folder. This should be the location of your Liferay bundle (in this case, your Liferay 7.0.4 GA5 bundle).

First, check build.gradle to see if it has a reference to a deployDir. If it does (which is the case in repositories like Audience Targeting), it will take precedence over any configuration file, you will need to modify this value in order to point to your desired deployment folder. In a default Liferay bundle where the OSGi and deployment folders have not changed, make sure to either /deploy at the end of the path if you wish for hot deploy to take care of things, or /osgi/modules if you'd like to deploy it directly to where OSGi is monitoring changes.

liferay {
    deployDir = new File("/path/to/liferay/home/deploy")
}

If there is no reference to deployDir inside of build.gradle, you have two options. You can either add it to build.gradle for each subrepository, or you can modify gradle.properties for each subrepository to specify the value for liferay.home. The latter is recommended, just because it matches up with how things normally happen elsewhere in Liferay source.

liferay.home=/path/to/liferay/home

Step 5: Deploy Clustering Modules

If you prefer something that imitates the commands that were published in the original announcement, you can do the following:

cd com-liferay-portal
../gradlew :apps:foundation:portal:portal-cluster-multiple:deploy
cd -

cd com-liferay-portal-cache
../gradlew :apps:foundation:portal-cache:portal-cache-ehcache-multiple:deploy
cd -

cd com-liferay-portal-scheduler
../gradlew :apps:foundation:portal-scheduler:portal-scheduler-multiple:deploy
cd -

If you prefer something that imitates commands you might already be familiar with in working with a Blade workspace, you can do the following:

cd com-liferay-portal/portal-cluster-multiple
blade gw deploy
cd -

cd com-liferay-portal-cache/portal-cache-ehcache-multiple
blade gw deploy
cd -

cd com-liferay-portal-scheduler/portal-scheduler-multiple
blade gw deploy
cd -