Learn how to build and test a simple web application using Gradle and Open Liberty.
You will learn how to build and test a simple web servlet application using Gradle.
The .war
plug-in compiles and builds the application code.
The liberty
Gradle plug-in installs the Open Liberty runtime, creates a server, and installs the application to run and test.
The application displays a simple web page with a link. When you click that link, the application calls the servlet to return a simple response of Hello! Is Gradle working for you?
.
One benefit of using a build tool like Gradle is that after you define the details of the project and any dependencies it has, Gradle automatically downloads and installs the dependencies.
Another benefit of using Gradle is that it can run repeatable, automated tests on the application. You could, of course, test your application manually by starting a server and pointing a web browser at the application URL. Automated tests are a much better approach because you can easily rerun the same tests each time the application is built. If the tests don’t pass after you’ve made a change to the application, the build fails, and you know that you introduced a regression that requires a fix to your code.
Using this guide, you will create a Gradle build definition file (build.gradle
) for the web application project, and use it to build the application.
You will then create a simple, automated test, and configure Gradle to run it after building the application.
The web application that you will build using Gradle and Open Liberty is provided for you in the start
directory so that you can focus on learning about Gradle.
The application uses the standard Gradle directory structure.
Using this directory structure saves you from customizing the build.gradle
file later.
All the application source code, including the Open Liberty server configuration (server.xml
), is in the src
directory:
└── src
└── main
└── java
└── resources
└── liberty
└── config
└── webapp
└── WEB-INF
Now you’re ready to install Gradle, if you don’t already have Version 3 or higher. The Gradle installation page gives you alternatives for installing Gradle based on your operating system.
Test that Gradle is installed by running the following command in a command line where you installed Gradle:
gradle -v
If Gradle is installed properly, you should see information about the Gradle installation similar to this line:
------------------------------------------------------------
Gradle 4.1
------------------------------------------------------------
Build time: 2017-08-07 14:38:48 UTC
Revision: 941559e020f6c357ebb08d5c67acdb858a3defc2
Groovy: 2.4.11
Ant: Apache Ant(TM) Version 1.9.6 compiled on June 29 2015
JVM: 1.8.0_144 (Oracle Corporation 25.144-b01)
OS: Mac OS X 10.12.6 x86_64
You can also view the default tasks available by running the following command:
gradle tasks
The project configuration is defined in the Gradle settings and build files. You will create these project configurations one section at a time.
First, create a settings.gradle
file in the current directory, where you cloned the project (at the same level as the README.adoc
file):
Add the line to name the project GradleSample
.
link:finish/settings.gradle[role=include]
This settings.gradle
file isn’t required for a single-module Gradle project. Without this definition, by default, the project name will be the name of the folder in which it is contained (guide-gradle-intro
).
Create a build.gradle
file in the current directory where you cloned the project (at the same level as the settings.gradle
and the README.adoc
files):
Let’s go through the parts of the build.gradle
file so that you understand each part.
-
Plug-ins: The plug-ins required to build the project.
-
BuildScript: Where to find plug-ins for download.
-
Repositories: Where to find dependencies for download.
-
Dependencies: Java dependencies that are required for compiling, testing, and running the application are included here. You can also define your Liberty runtime dependency in this section.
-
Liberty: Configuration for the Liberty plug-in.
You will build the build.gradle
file piece by piece.
The first information added to the build.gradle
file defines the .war
and liberty
plug-ins that you want to use.
The .war
plug-in contains all the tasks to compile Java files, build the WAR file structure, and assemble the archive.
The liberty
plug-in contains the tasks used to install the Liberty runtime and create and manage servers.
The group
, version
, and description
define this project.
The compatibility and encoding settings are for Java.
link:finish/build.gradle[role=include]
The buildscript
section defines where to find the plug-ins you are using in the build.
This guide uses version 2.1 of the liberty
plug-in, which is available from the Maven Central Repository.
link:finish/build.gradle[role=include]
The repositories
section defines where to find the dependencies that you are using in the build.
For this build, everything you need is in Maven Central.
link:finish/build.gradle[role=include]
The dependencies
section defines what is needed to compile and test the code. This section also defines how to run the application.
The providedCompile
dependencies are APIs that are needed to compile the application, but do not need to be packaged with the application because Liberty provides the implementation at run time.
For example, the HelloServlet.java
class depends on javax.servlet-api
to compile, but since Liberty provides that API, it does not need to be packaged with your application.
The testCompile
dependencies are needed to compile and run tests.
The liberty
plug-in provides the libertyRuntime
dependency definition that specifies the version of the Liberty runtime you want to use.
This project uses Open Liberty 17.0.0.2 or later.
At the time of writing for this guide, Version 17.0.0.3 was used.
Other versions of the WebSphere Liberty runtime are also available in Maven Central.
link:finish/build.gradle[role=include]
The ext
section shows the Gradle extra properties extension that allows you to add properties to a Gradle project.
If you use a value more than once in your build file, you can simplify updates by defining it as a variable here and referring to the variable later in the build file.
We define variables for the application name, ports, and the context-root.
link:finish/build.gradle[role=include]
The next section provides configuration for the liberty
plug-in.
In the liberty
extension, we configure the Liberty server, which includes the following settings:
-
name: The server name.
-
configFile: The server configuration file.
-
bootstrapProperties: Bootstrap properties that are written to the server’s
bootstrap.properties
file. -
packageLiberty: Specifies to only package the
usr
directory in thebuild/GradleSample.zip
file.
link:finish/build.gradle[role=include]
So what’s not configured? By default, when the liberty
and the .war
plug-ins are applied, the default WAR file is installed to the apps
folder.
Omitting this definition is the same as including the following line:
apps = [war]
You can also install applications to the dropins
folder.
Also, by default, a loose application is installed to your Liberty server.
Instead of installing a WAR archive, an XML file (GradleSample.war.xml
) is installed that describes the location of the application classes, resources, and libraries.
This is useful for development because you only need to recompile your code, rather than repackaging your WAR file to see application updates live on the server.
If you want to turn off loose application support, add the following line:
looseApplication = false
One of the benefits of building an application with a build system like Gradle is that it can be configured to run a set of automated tests.
The war
plug-in extends the Java plug-in, which provides test tasks.
You can write tests for the individual units of code outside of a running application server (unit tests), or you can write them to call the application that runs on the server (integration tests).
In this example, you will create a simple integration test that checks that the web page opens and that the correct response is returned when the link is clicked.
We configured the Gradle project to start the server with the application installed before running the test. After running the test, the server is stopped.
Create the test class src/test/java/io/openliberty/guides/hello/it/EndpointIT.java
:
link:finish/src/test/java/io/openliberty/guides/hello/it/EndpointIT.java[role=include]
The test class name ends in it
to indicate that it contains an integration test.
The integration tests are put in the it
folder by convention.
Configure the Gradle build file to run the integration tests in the */it/**
folder.
link:finish/build.gradle[role=include]
The systemProperties
configuration defines some variables needed by the test class.
While the port number and context-root information can be hardcoded in the test class, it is better to specify it in a single place like the Gradle build.gradle
file, in case they need to change.
The systemProperties
section passes these details to the Java test program as a series of system properties, resolving the liberty.text.port
and war.name
variables.
The following lines in the EndpointIT.java
test class uses these system variables to build the URL of the application:
link:finish/src/test/java/io/openliberty/guides/hello/it/EndpointIT.java[role=include]
In the test class, after defining how to build the application URL, the @Test
annotation indicates the start of the test method.
In the try
block of the test method, an HTTP GET
request to the URL of the application returns a status code.
If the response to the request includes the string Hello! Is Gradle working for you?
, the test passes.
If that string is not in the response, the test fails.
The HTTP client then disconnects from the application.
link:finish/src/test/java/io/openliberty/guides/hello/it/EndpointIT.java[role=include]
In the import
statements of this test class, you’ll notice that the test has some new dependencies.
Earlier we added some testCompile
dependencies.
The Apache commons-httpclient
and junit
dependencies are needed to compile and run the integration test EndpointIT
class.
The scope for each of the dependencies is set to testCompile
because the libraries are needed only during the Gradle test phase and do not need to be packaged with the application.
Now, during the build, Gradle installs the application and then runs any integration test classes in the it
folder.
The directory structure of the project should now look like this example:
└── src
├── main
│ └── java
│ └── resources
│ └── webapp
│ └── WEB_INF
│ └── liberty
│ └── config
└── test
└── java
You can now run the command gradle build -i
to build the application and test the application.
The -i
option provides additional information on the command line.
The build takes a little longer than before the test existed, but expect to see the browser opened with the test summary displayed.
To see whether the test detects a failure, change the response string in the servlet src/main/java/io/openliberty/guides/hello/HelloServlet.java
so that it doesn’t match the string that the test is looking for.
Then rerun the Gradle integration tests with a gradle integrationTest -i
command, and check that the test fails.
The complete build.gradle
file should now look like this example:
link:finish/build.gradle[role=include]
You built and tested a web application project with an Open Liberty server using Gradle.
You can quickly create this project structure by using the Liberty App Accelerator and choose to create a Gradle project.