Welcome to Part 5 of the Gradle Tutorial. In the previous episode i.e. Part 4, we took a look at building Java Web Applications via Gradle.
In this part of the tutorial, we shall look at the App Engine Gradle plugin. If you are an App Engine developer, you will know that there are multiple ways in which you can work with your App Engine projects. You could use the Google Eclipse plugin, command line and even Maven to handle all things from build, local dev server and finally deployment to the live instance.
Well, you can now do all of that via Gradle too. You may ask why use Gradle, when you may already have got used to one of the other mechanisms to deal with your App Engine Developer flow (Eclipse plugin, Maven or Command Line). I think it is important to understand Gradle for the simple reason that over the last few months, we have seen that App Engine modules can be added to your Android applications inside of Android Studio. I personally think that we will over time see more of that happening and with Google putting its weight behind Android Studio + Gradle, we need to be ready for that. And trust me, since you already know quite a bit of Gradle by now, things fall in place quite well.
To summarize, this episode will be about a basic App Engine application that we shall build, run locally and deploy to the Cloud via Gradle App Engine plugin and its related tasks. Let’s get started.
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. You are also familiar with basic Java Web Application projects, some of that we covered in Part 4.
Our Project Scenario
For this episode, we shall look at a basic Hello World App Engine project that I have created in the following folder structure as shown below::
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 in brief about the project and other requirements:
The structure above is a standard App Engine Java project. I used the Eclipse plugin to generate it and place it in the folder (helloappenginegradle). There is nothing more to the App Engine project for now.
The folder structure follows convention that we would like to follow for Gradle. So we have the src / main folder and inside of that we have the java and the webapp folder. Notice that we have the build.gradle project at the root of the project folder.
The java folder contains the Java sources and other resource files. We have the standard Hello Gradle Servlet present in the sources.
The web folder contains any Web resources and the standard WEB-INF folder. The WEB-INF folder contains web.xml and more importantly the appengine-web.xml file that has App Engine application specific configuration data. For e.g. the <application> and <version> values, which will be used to deploy to the App Engine project id that we have created via the Google Cloud Console.
I will assume that you are aware about the basics of App Engine deployment and that you have a Google Account, have created a Project via the Google Cloud Console and have correctly placed the Application Id value in the <application> tag in appengine-web.xml file.
The build.gradle file that is found at the root folder i.e. \helloappenginegradle is shown below. We will go through it step by step.
Let us go through the file in brief:
We are applying the WAR plugin. This by default also applies the java plugin as we have seen in earlier episodes.
We then apply the AppEngine plugin.
We then define 3 variables and you may not define it and directly provide the values but it is just good practice. The variables are the App Engine Project Id that you would have created via the Google Cloud Console. The email address is the account which owns this project and finally we are specifying the App Engine SDK Version.
You will notice a new closure buildscript. This is nothing to do with App Engine and is generally used to specify dependencies that the build script will need to it. In our case, this script requires the App Engine Gradle library to be present and hence we are specifying it via the normal dependency and specifying from which repository to take it.
Next we have the dependencies that this project source code needs to compile. The standard App Engine, Servlet, etc JAR files are specified. At the end of this tutorial, you will also find a small note on how to include many other dependencies that your code might need around JDO/JPA, etc.
Finally, we have the appengine closure that is required to specify various things like which port the local Dev Server will be started on, the authentication mechanism for deployment process and ofcourse the appId and version of the application to be deployed. We will cover more on this as we move forward here but if you are familiar with App Engine, it should sound familiar.
You can look at the additional tasks that have been added by opening up a command window/terminal and navigating to the root folder.
Simple fire the following:
and you should see additional tasks available via the App Engine plugin that you have applied. Some of the key tasks that were added and which we will use are highlighted in bold (appengineRun , appengineUpdate). If you are familiar with App Engine, most of the tasks can do is something that you would have tried out anyways. Tasks for every aspect of dealing with App Engine i.e. Logs, Cron Jobs, Starting/ Stopping and more are available.
Running the Local Dev Server
This is a common task that one does while doing development. Assuming that you have download the project from Github and/or have your own App Engine project with the build.gradle file, you can fire the following command:
You should see the following output in the console:
Notice, how Gradle takes care of the task dependencies by checking if the SDK is present locally or not. If not, be very patient, since it will download the whole SDK (200MB approximately).
It then compiles the code, builds the WAR file, explodes that and then launches in the in-built web server via appengineRun. You can now go to http://localhost:8888 in the browser and it should navigate on to your index page. Remember that you can specify several parameters to guide the HTTP Server that will be launched on your machine. This is done via the appengine closure and for our build.gradle file, we had specified the httpPort as 8888. A section of that closure is shown below:
If you look at the documentation for the App Engine plugin, you will also find several other properties that you can specify to control the Web Server launch. I have listed down some of them from the documentation.
httpAddress: The IP address for the local development server (if server is to be accessed from network). Default is localhost.
httpPort: The TCP port which local development server should listen for HTTP requests on (defaults to 8080).
warDir: Web application directory used for local development server (defaults to build/exploded-war).
disableUpdateCheck: Disables the Google App Engine update check if set to true.
jvmFlags: The JVM flags to pass on to the local development server. The data type is a List.
At any point in time, if you wish to stop the server, you can do that via the
gradle appengineStop task.
Deploying to App Engine
Once you have developed your app, tested in locally and if everything looks good, the next step is to deploy the application to App Engine.
This is a fairly interesting task and you can do that via the following command:
But before you go right ahead and launch it, let us recollect first what is needed to deploy the application to App Engine.
You need to have the Application Id and version of the App Engine application that you want to deploy in the cloud
You need to have your Account Name and Password ready, so that you can be authenticated/authorized to move forward with deployment
Given the above two things and ofcourse your project files, the appengineUpdate task is clever enough to do all the heavy lifting for you.
However, it is important to understand how the script will authenticate itself via your credentials. You have to make a decision for that and whether you want your Admin credentials to be remembered via a cookie or not. The Plugin gives you the flexibility to control it via any process that you see fit for your deployment workflow.
So, you can opt for a prompt for password mechanism , where you will be asked for a password and you can enter that, before the deployment process moves forward. Else, you could also opt for a OAuth2 mechanism, where a browser window launches for you to login and authorize your Google Account for deployment and then you need to paste the Authentication Token to move forward.
It can be quite confusing the first time, so let me show you both the options. But first, see where that magic is specified in the build.gradle file.
The required snippet from the file is shown below (this could be different that the one that is hosted and which you may download via the Github link)
Specifically, focus on the appcfg closure.
It has an email property that is my Google Account under which I have created the hellogradle project.
It has a noCookies property that ensures that my Sign In credentials will not be stored. If this property is set to true, then every single time that you do an update, it will require that the authentication process is done , whether it is oauth2 or via the password.
It contains an app closure that has the Application Id and version of the application that has to be hosted on App Engine.
To deploy the project, we will fire the following command:
This will go through the necessary steps and you will find that it waits at the password prompt as shown below:
Go ahead and start typing the password inside the console/terminal itself and press enter, it will validate the password and go ahead with the deployment as shown below:
Now, you can also do the following:
If you do not want to enter your password again, you can specify the password in plain text via the password property.
Alternately, since the password is now captured, you could opt to go for the noCookies = false and let the process use the password that it knows.
I suggest that you try out various combinations. As per the documentation, you can even specify the password in a separate properties file. You can try that too.
Now, let us try the following snippet – which bypasses the password prompt and instead goes for the OAuth2 mechanism. The only change we have made is that we have introduced another property of the appcfg closure called oauth2 and made that as true.
The snippet is shown below:
If we now run the gradle appengineUpdate task, we get the entire OAuth2 Dance started via the browser.
First, you will see the normal tasks getting executed as shown below:
Next, it will popup a browser window, where you will authorize the process of deployment via your account. A screenshot is given below:
Once you accept the process, it will show the following:
You need to now paste this code and go back to the terminal. Simply paste it there and the rest of the process of deployment moves forward:
This completes our little tutorial on using the App Engine Gradle plugin. There is a lot more to it, and you should check out the complete documentation.
App Engine JDO/JPA Code
If you are planning to migrate your existing App Engine projects over to using Gradle as your build tool, you will need to do a bit more work than what we have seen in this episode. Specifically, I would advise that you look at the following 2 points:
If you are using Eclipse, you will notice that there are several App Engine JAR files that are linked up in the Java Build Path. You should carefully add compile dependencies to your build.gradle file for all these JAR files. For e.g. take a look at this Stack Overflow question where the sample build.gradle file contains various dependencies. You will need to be accurate with the versions for your project. For e.g. some additional compile dependencies than the ones that we have seen so far could be something like the one shown below:
If using JDO and JPA code, you should keep in mind that the Entity classes need to be enhanced to weave in the persistent code. To do that, the App Engine plugin for Gradle, provides a closure named enhancer, the documentation for which I produce below:
Within appengine you can also define a closure named enhancer:
version: The version (v1/v2) parameter for App Engine datanucleus enhancer task
api: The api (jdo/jpa) parameter for the App Engine datanucleas enhancer task
enhanceOnBuild: Automatically run the enhancer (defaults to false)
version = "v2"
enhanceOnBuild = true
This tutorial helped you understand how to build , locally run and deploy your App Engine Applications.
Google App Engine modules are now supported inside of Android Studio. As a result of that, it is important that you understand what went on in this chapter. It will make the task of understanding the Gradle build files for Android Studio projects that contain an App Engine module that much easier.
In the next episode, we shall look begin our journey to Android Studio. Gradle files are generated by default for you in Android Studio, but our learnings so far from Part 1 to Part 5 of this series will hold us in good stead to understand and modify stuff as needed.
Till then, Happy Gradling!
App Engine Gradle Plugin
Stack Overflow link for JDO/JPA Class Enhancement