Gradle Tutorial : Part 4 : Java Web Applications

Romin Irani
Romin Irani’s Blog
7 min readAug 12, 2014

Welcome to Part 4 of the Gradle Tutorial. This part takes off from Part 3 , where we covered building multiple interdependent Java projects.

LAST UPDATE : December 27, 2017

— Integrated Gretty plugin
— Updated Source Code

In this part of the tutorial, we shall look at building Java Web Applications via Gradle. As is the pattern, we shall have a multi-project scenario where we will have one Java Project that has some utility class and which is built separately. And then we have a Java Web Project that is dependent on this project and has JSP/Servlets and so on.

In the process, we shall look at 2 additional plugins that Gradle provides, which will make our task easier. The plugins are:

  1. War Plugin : This plugin allows us to compile and assemble a WAR (Web Application Archive) file from our Java Web Application.
  2. Gretty Plugin : This plugin allows us to run our web application inside of a Jetty container. Very useful to test out the project quickly.

This part assumes that you have a Gradle installation on your machine and the basic environment is setup. For more information on that, refer to Part 1. Additionally, you know the basics of using the Java plugin in Gradle, which we covered in Part 2 and building multiple and interdependent Java projects that we covered in Part 3.

Our Project Scenario

For this episode, we shall look at 2 projects that are arranged under a common directory. Our root directory is going to be called mywebapp and inside of that we shall have 2 folders that will contain individual projects as shown below:

mywebapp
|- utils
|- web

All the project source code , including the build files is available on Github. Please download it from here and keep it available on your machine, so that you can follow the tutorial and run it along as we go through this episode.

Now, let us talk about the dependencies. These dependencies are something like this:

  1. utils: This project contains some utility code and hence it will not depend on any of the other projects. The Java code in this project depends on an external Java Date Time Library : Joda Time. So we will need to have that dependency defined for this project.
  2. web: This is a Java Web Application project, that just has a simple Servlet and JSP file, along with the web.xml file. This project depends on the utils project, since it uses the utility Java class from there. Along with that dependency, it also has dependency on the Servlet Jar file that is needed to compile Java HTTP Servlet code.

Multiple Gradle files

As we had seen in the last episode, it is better to create multiple build.gradle files, so that we can customize and maintain the build specific requirements for each project in a much more maintainable fashion.

In essence, what we are ending up with is a structure that looks like the following:

/mywebapp
|- /utils
|- build.gradle
|- (Java Sources and files)
|- /web
|- build.gradle
|- (Java Sources , JSPs and files)
|- settings.gradle
|- build.gradle

settings.gradle

Since, we have two projects (utils and web), our settings.gradle will reference both the project as shown below:

include ":utils",":web"

build.gradle

The build.gradle file that is found at the root folder i.e. \mywebapp is shown below. You will notice that since both of these are Java projects, we are applying the Java plugin and also specifying that Maven Central be used for downloading any dependent libraries:

subprojects {

apply plugin : "java"

repositories {
mavenCentral()
}
}

Now that we have got the common configuration out of the way, let us look at the individual build.gradle files that will be present in each of the projects i.e. web and utils.

utils project — build.gradle

The build.gradle file for the utils project is shown below:

apply plugin: "java"
dependencies {
compile "joda-time:joda-time:2.9.4"
}

The above is a straight forward build.gradle file. It is applying the Java plugin. You need not mention it since it is specified for all subprojects in the common build.gradle at the root folder, but I am just mentioning it here, so that you have a complete build.gradle file.

The next line defines the dependency on the joda-time library. We have got the group id, artifact id and the version from the Maven Central library over here.

Please note that if you download the source code from Github, the utils project only contains a single Java utility class (DateUtils.java) under the conventional directory structure as shown below:

gradle-ep4-1

Note the conventional structure i.e. inside of the utils project. I have the src/main/java folder and inside of that are my package structure and Java class names. So for example, in the above case, the Java class is DateUtils and its package is com.mindstorm.apputils.

web project — build.gradle

Now, let us look at the build.gradle file for the web project. We will introduce the Gretty plugin a bit later.

The initial version of the build.gradle file is shown below:

apply plugin: "war"dependencies {
compile project(":utils")
compile "javax.servlet:servlet-api:2.5"
}

Here we are applying the war plugin. Additionally, we are making this project dependent on the utils project and on the Servlet API 2.5 version, since we have some Servlets in this project.

As per the documentation "The War plugin extends the Java plugin to add support for assembling web application WAR files. It disables the default JAR archive generation of the Java plugin and adds a default WAR archive task."

The plugin also adds the war and assemble tasks to the tasks available for the project.

You can look at the additional tasks that have been added by opening up a command window/terminal and navigating to the web folder.

Simple fire the following:

gradle tasks

and you should see additional tasks available via the war plugin that you have applied:

Build tasks
-----------
assemble - Assembles the outputs of this project.
build - Assembles and tests this project.
buildDependents - Assembles and tests this project and all projects that depend on it.
buildNeeded - Assembles and tests this project and all projects it depends on.
classes - Assembles main classes.
clean - Deletes the build directory.
jar - Assembles a jar archive containing the main classes.
testClasses - Assembles test classes.
war - Generates a war archive with all the compiled classes, the web-app content and the libraries.

Building the WAR file

Since we have made the web project depend on the utils project, we can build the entire Web Application, by going to the web folder in the terminal and firing the following command:

gradle assemble

You should see the following output in the console:

$ gradle assemble
BUILD SUCCESSFUL in 11s
4 actionable tasks: 4 executed

Notice, how Gradle takes care of the dependencies by compiling the utils project first and then building out the web project.

At this point in time, you should have a build folder inside your web folder. Go to the libs folder inside the build folder and you will find that the .war file has been generated for you.

The Gretty Plugin

It would be cool if we could not just build out the WAR file but also deploy it inside of the Jetty container and run the application for us to test out. That is exactly what the Gretty plugin can do for you.

To do this, we will modify our build.gradle file for the web folder as shown below: (Note : If you have downloaded the file from Github, then these changes are already present in the web/build.gradle file)

apply plugin: "war"
apply from: 'https://raw.github.com/akhikhl/gretty/master/pluginScripts/gretty.plugin'
dependencies {
compile project(":utils")
compile "javax.servlet:servlet-api:2.5"
}
gretty {
httpPort = 8080
}

Notice the additional entries that we have added in bold. We have simply applied the Gretty plugin and also provided one of the standard properties (httpPort) available to configure the Jetty Web Server when it is launched i.e. the HTTP Port. We have specified 8080 as the value.

Save the above in the build.gradle file. Go to the web folder again and fire the following command again:

gradle tasks

You will notice that the additional tasks around Gretty have also got added now (only a few of the Gretty tasks are shown in the output below):

Gretty tasks
---------------------
appAfterIntegrationTest - Stops server after integration test.
appBeforeIntegrationTest - Starts server before integration test.
appRestart - Sends 'restart' command to a running server.
appRun - Starts web-app inplace, in interactive mode.
appRunDebug - Starts web-app inplace, in debug and interactive mode.
appRunWar - Starts web-app on WAR-file, in interactive mode.
appRunWarDebug - Starts web-app on WAR-file, in debug and interactive mode.
appStart - Starts web-app inplace (stopped by 'appStop').
appStartDebug - Starts web-app inplace, in debug mode (stopped by 'appStop').
appStartWar - Starts web-app on WAR-file (stopped by 'appStop').
appStartWarDebug - Starts web-app on WAR-file, in debug mode (stopped by 'appStop').
appStop - Sends 'stop' command to a running server.
archiveAllProducts - Archives all configured gretty products.

The tasks look straightforward. Our goal should be now to assemble the WAR, deploy the same into Gretty and run the server too.

To do that, simply give the following command in the web project.

gradle appRun

This will build things (if they are updated) and the web server will be started.This means that the server has got started with our web application and is available at http://localhost:8080/web.

If we navigate to the URL in a browser, we see the web application come up nicely as shown below:

You can even visit the servlet configured if you want i.e. http://localhost:8080/web/daystogo.

Moving forward

This tutorial helped you understand how to build your Java Web Applications using Gradle. Specifically, we looked at how the WAR and Gretty Plugin makes this possible.

References

--

--

Romin Irani
Romin Irani’s Blog

My passion is to help developers succeed. ¯\_(ツ)_/¯