Blogs

Liferay 7 Development, Part 2

Introduction

In part 1, the filesystem access portlet project for Liferay 7 was introduced.

In this part, we're going to use Blade and Gradle to set up our basic project structure.

We're not going to do much in the way of code in this part, it's going to be enough that we get all of our modules defined and ready for development in future parts of the blog.

The Tools - Gradle  https://gradle.org/

So if you've been in Liferay development for a while, I'm sure you know the history of Liferay's build tool selection, but we'll review anyway.

First there was Ant.  Of course, when Liferay started using Ant, everybody was using Ant.  It was really the only game in town.  And with Ant came the Liferay SDK and it's rigid structure for where projects had to be and how they had to be structured.

And that was it, for a long time, much longer than necessary.  The rest of the world had moved on to Maven, discarding the verbose and declarative nature of the Ant build.xml file, but Liferay stuck with Ant and the SDK...

With Liferay 6.1, however, Liferay started to catch up and the Liferay Maven artifacts started coming out.  It was rough at first, but by the time we were on to 6.2 Maven support was all there and we were finally able to discard the rigid SDK approach and free our projects from holding all of the dependency jars.

But the development world kept moving on, discarding Maven for cooler build tools with awesome features and flexibility that Maven couldn't offer.

Instead of slowly integrating a new tool in, Liferay went all-in with the introduction of Gradle support in Liferay 7.

Liferay is adopting Gradle for its projects (modularization of the core, side projects, etc.) so it's a really safe bet that Gradle support is going to be around for a while.

Me, I'm much more pragmatic; if Liferay is going to use this tool for their projects, I want to use the tool too; I don't want to be the odd ball looking for support on something they may not be interested in supporting some time in the future.

So Gradle it shall be.  Go ahead and download and install Gradle on your system; I'm not going to go into details here, but you really shouldn't have any problems installing it and their documentation and other documentation online will be able to help you get the job done.

The Gradle Wrapper

I want to take a moment and mention something you'll often see in Gradle projects, the gradlew[.bat] files and the gradle directory.  These guys are the Gradle Wrapper.

The wrapper is basically a fixed version of Gradle that is installed and run locally within the project directory.  Why, when you can install Gradle, would you want to do such a thing?  Well, if you're passing a project to a developer that doesn't have Gradle installed (like you when you pull down Liferay 7 projects for the first time), you may not have Gradle installed; the wrapper allows you to build the project anyway.  It's also going to stick to the version of Gradle used to install the wrapper; this removes version-specific issues from the build process since the right version of Gradle will be with the project regardless of what version the developer has.

If you're not creating projects, you probably won't need to set up the Gradle Wrapper.  If you're creating a project to share with others, when you initialize the Gradle project you'll get the gradle wrapper in there too.

After the wrapper is generated, you're going to want to use the wrapper from that point forward.  Instead of issuing the command "gradle build" to do a build, instead you'd use the wrapper version, "gradlew build"

The Tools - Blade  https://github.com/liferay/liferay-blade-cli

Okay, some explanation here before we get too far in; there's like two Liferay projects which you may find referred to as Blade.

The one we're going to use, the Blade CLI, well we'll get to that one in just a moment.

The other one is the Blade Samples project, https://github.com/liferay/liferay-blade-samples.  The Blade Samples project is a big repository of Liferay 7 modules, a set of 31 (currently), and all of these provided using different build tools (BND, Gradle, Liferay's Gradle plugin, and Maven).  You can use to, say, master some of the OSGi module stuff using your favorite build tool and, once you understand that, can review the implementation using a different build tool so you could see how to translate what you know to the new build tool.  All of that said, we won't really come back to the Blade Samples again, but I did want to highlight it as it can be a valuable resource for you in the future.

Back to the Blade CLI.  This command line tool is a utility to help scaffold together your gradle-based Liferay modules.  It can generate the foundation for you so you can jump right into flushing out your code.

If you haven't already done so, install the Blade CLI per the instructions on the Blade website.  If you have already installed it, you should update it using the command:

[sudo] blade update

Note you only need the sudo portion if you are on a system that has a sudo command; if you don't know if you do have this command, it is likely that you do not have it.

The Project Structure

One of our requirements is to build full OSGi-compliant Liferay 7 modules.  That's a mouth full, but it draws out an important point.

OSGi-compliant modules means we're going to be building jars.  OSGi bundles, actually, but in Liferay we call them modules because, well, they actually will include some Liferay specific stuff and have some Liferay runtime container dependencies.  Liferay calls these guys modules, so we will too.  When someone says bundle, just know they're talking about modules.

Now if you're not familiar w/ what that really means, well then it's time to start learning about them.  If I had to boil it down to something simple, I guess I'd say it's pretty close in concept to the Spring Framework - small pieces of functionality that are wired together at runtime to build a functional application.  Obviously it is a lot bigger than that with multiple classloaders, a slew of runtime dynamic configuration support, etc.

But thinking along the lines of Spring we can come up with a pretty good architecture for our portlet implementation.

Now we could just put all the code into one bundle and everything would work, it would be simple, and it would get the job done.  But if we're really going to learn something here, let's over-architect it as it will make a better educational experience.

So, thinking along the Spring lines, we know we're going to have some sort of "service" that we'll use to hold our file system access business logic.  Like in Spring, we'll separate that into an API module (the Spring interfaces) and the Service module (the concrete implementation classes).  And yes, we still have our portlet to create, so that will be a module too.

To get back on task, our project will consist of one set of parent build files and 3 modules.

Building The Project Structure

Okay, we have the background for the tools behind us, time to build out the structure, so let's get to it.

So first you need a directory somewhere where you're going to be creating everything.  I'm going to create the "filesystem-access" folder in my local projects directory; every other step below and in the other parts of this blog will all be taking place within this folder.

Step 1 - Set Up Workspace

The first thing we need to do is initialize the Blade/Gradle environment in our project directory:

$ blade init
Note that this command will fail if there are files in the directory, so you want to do this before any other steps.

The structure that you get here is actually referred to as the "Liferay Workspace".  The Liferay Workspace is a container for building all of your plugins.  It's kind of like the old SDK except it is based on Gradle (not Ant) and only distinguishes between modules and themes (unlike all of the different plugin types supported by the SDK).

We'll be using this workspace as our foundation for the project.  For a project that will be multiple modules, the Liferay Workspace is a good foundation.

Step 2 - Create The Modules

We will be switching to the Blade CLI to create out modules.  Change to the modules/apps directory (you may need to create the apps directory in modules) and use the following commands will be executed to create the modules:

$ blade create -t api -p com.liferay.filesystemaccess filesystem-access-api
$ blade create -t api -p com.liferay.filesystemaccess.svc filesystem-access-svc
$ blade create -t mvcportlet -p com.liferay.filesystemaccess -c FilesystemAccessPortlet filesystem-access-web

Step 3 - Clean Up The Modules

Since we created two projects from the api template, we're going to take some time to undo that effort.

  • In the filesystem-access-api module, add a blank interface, com.liferay.filesystemaccess.api.FilesystemAccessService (we'll fill it out in the next blog).
  • In the filesystem-access-api module, delete the com.liferay.filesystemaccess.api.FilesystemAccessApiActivator class.
  • In the filesystem-access-svc module, change the package from com.liferay.filesystemaccess.svc.api to com.liferay.filesystemaccess.svc.internal.
  • In the filesystem-access-svc module, add a blank class, com.liferay.filesystemaccess.svc.internal.FilesystemAccessServiceImpl (we'll fill it out in the next blog).
  • In the filesystem-access-svc module, delete the com.liferay.filesystemaccess.svc.FilesystemAccessServiceActivator class.

Conclusion

Okay, so far we haven't done very much, but let's review anyway:

  • We reviewed a little about Gradle and Blade.
  • We created a Liferay Workspace to hold our modules.
  • We created our initial yet empty modules.

In the next blog post we'll get into some real development stuff, building out a DS service layer...

The project has been pushed up to GitHub, you can access it here: https://github.com/dnebing/filesystem-access

The files for this part of the blog are in branch part-2: https://github.com/dnebing/filesystem-access/tree/part-2

Thanks for your article. One addition: With blade 2.0.2 the template "mvcportlet" is called "mvc-portlet".
Kind regards