Start Here !

Welcome to my website. Find articles, presentations, tutorials, experiments on various technologies.

You can get in touch with me anytime at

r o m i n . i r a n i @ m i n d s t o r m s o f t w a r e . c o m

I am also active on Twitter (do follow me) and on Google+.

 

Posted in Uncategorized | Leave a comment

Gradle Tutorial : Part 10 : Consuming Endpoints in Android Code

Welcome to Part 10 of the Gradle Tutorial. In the previous episode i.e. Part 9, we looked at writing Cloud Endpoints using Objectify as the Persistence layer. We wrote a Quote Endpoint class that exposed various methods like list Quotes, add Quotes, remove Quotes and modify Quotes.

This tutorial adds to both Part 8 and Part 9 of the tutorials, where it will show how to consume the Endpoints code inside of your Android application. This would sort of logically complete the step that we set to do earlier in the series, which includes:

  • Generate a Android Project in Android Studio
  • Add an App Engine module with Cloud Endpoints to the Android project, thereby making it a multi-module project. In Part 8 and Part 9, we looked writing Cloud Endpoints and testing them locally via the API Explorer.
  • In this episode, we shall look at consuming that Endpoint in the Android code. This would really make you as an Android developer appreciate the power of Endpoints since within the same dev environment, you can do your client development (Android app) and Server side Code (App Engine + Cloud Endpoints) and then integrate and test it out locally.

If you have reached this part of tutorial without understanding the earlier parts, I suggest to go through Parts 7 , 8 and 9.

ep8-logo

This part assumes that you have installed Android Studio on your development machine and that you are familiar with basic Gradle commands, project structure and files as we have seen in the series so far.

I have used Android Studio (Beta) 0.8.6 on Windows for this blog post. It is not necessary to have the same version or the OS, things should be pretty much similar from a Gradle perspective.

The Android Studio project for this episode has been hosted on Github. If you want, you can pull that down.

We shall cover the following in this blog post:

  • Begin with where we left of in the last episode i.e. we created a Quote Endpoint service that allowed us to expose various methods like listQuote, insertQuote, updateQuote, removeQuote and so on.
  • Visit our Android Application and integrated the Quote Endpoint Service into the code. This is not an Android tutorial and hence the integration will be kept simple. We shall simply retrieve a list of Quotes via the Service and use Toast to display the quotes. You should familiar though with using the Android AsyncTask to asynchronously invoke our API backend from the Android client.

Before we begin

Make sure that the following is valid for your setup:

  1. You have setup the Hello CloudEndpoints project either from Github or by following the earlier part of the series.
  2. You can launch a local dev server for api module and are able to visit the quoteEndpoint API via the API Explorer at http://localhost:8080/_ah/api/explorer
  3. You have added a few Quote records and the listQuote method is giving back atleast 1 or more Quote objects.

If not, I suggest to follow Part 9 and get your setup correct.

Endpoints Client Libraries generation

Since, we are going to be consuming i.e. invoking the Endpoints API from our Android application, we need to get hold of the client libraries that we can use to invoke the API.

Technically, since the Endpoints are REST API Services hosted over HTTP, you can always write your own HTTP networking code and handle the request/response data inside of your Android application. But this will be a time consuming affair.

Google Cloud Endpoints provides a way for us to generate the client side libraries. For those of you, who have used Eclipse plugin to develop Cloud Endpoints, you must be familiar with the step of Generating Client Libraries.

In Android Studio, when you build your api project, there is a lot of stuff going on behind the scenes. If you noticed carefully when doing the App Engine Gradle build, generate endpoint libraries was done for you. What this means is that all the networking, marshalling/unmarshalling code has been generated and wrapped by an easy to use Endpoint class that you can invoke from your Android code.

If you look closely into your directories on your machine, you will find that there is a build folder for your api project that got generated and a bunch of folders got generated there with libraries, .class files, source files and so on.

ep10-1

 

Since the whole stuff is integrated now, you don’t have to mess around with these files at all, unlike the Eclipse thing. But it is good to know what has got generated behind the scenes and so on.

Gradle Files

Just to recap your understanding of multi-module projects and their dependencies, take a look again at app/build.gradle . You will notice that the Android app project is dependent on the api project and mentions that dependency against the compile configuration as shown below:

ep10-2

 

Android Application

Let us first look at the Android application to see what we are going to do. The first screen is shown below:

device-2014-08-27-135012

We have just added an additional button Get Quotes. When we click that button, it will make a call to the Endpoints API , specifically the listQuotes method.  It uses the client libraries for that, which we shall see in a while.

Once it gets the quotes, it goes through the list and displays the quotes, one by one via Toast, as shown below:

device-2014-08-27-135050

The next few sections will take you through the code and we will be focusing only on the app module in the project.

activity_my.xml

Nothing much happening here. All I have done is add a Button to the layout as shown below. The onClick of the button invokes the getQuotes method in the MyActivity.java class.


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MyActivity">

<TextView
android:text="@string/hello_world"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView" />

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/getquotes"
android:id="@+id/btnGetQuotes"
android:layout_below="@+id/textView"
android:onClick="getQuotes"
/>
</RelativeLayout>

MyActivity.java

In this section, I will only highlight the method that is invoked when the Get Quotes button is clicked. As mentioned in the earlier section, we need to have a getQuotes method in the activity class as shown below:


public void getQuotes(View v) {
new EndpointsAsyncTask(this).execute();
}

Few things to note here:

  1. Observe how compact the code is.
  2. It invokes an Async Task class, since it is important to call this functionality in an Asynchronous fashion.
  3. The EndpointsAsyncTask class is a template class that I have borrowed from the brilliant post at https://github.com/GoogleCloudPlatform/gradle-appengine-templates/tree/master/HelloEndpoints

The class is shown below, I have modified it only so slightly.

EndpointsAsyncTask.java


package com.mindstorm.hellocloudendpoints;

import android.content.Context;
import android.os.AsyncTask;
import android.util.Pair;
import android.widget.Toast;

import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.extensions.android.json.AndroidJsonFactory;
import com.google.api.client.googleapis.services.AbstractGoogleClientRequest;
import com.google.api.client.googleapis.services.GoogleClientRequestInitializer;
import com.mindstorm.api.quoteEndpoint.QuoteEndpoint;
import com.mindstorm.api.quoteEndpoint.model.Quote;

import java.io.IOException;
import java.util.Collections;
import java.util.List;

class EndpointsAsyncTask extends AsyncTask<Void, Void, List<Quote>> {
private static QuoteEndpoint myApiService = null;
private Context context;

EndpointsAsyncTask(Context context) {
this.context = context;
}

@Override
protected List<Quote> doInBackground(Void... params) {
if(myApiService == null) { // Only do this once
QuoteEndpoint.Builder builder = new QuoteEndpoint.Builder(AndroidHttp.newCompatibleTransport(),
new AndroidJsonFactory(), null)
// options for running against local devappserver
// - 10.0.2.2 is localhost's IP address in Android emulator
// - turn off compression when running against local devappserver
.setRootUrl("http://10.0.2.2:8080/_ah/api/")
.setGoogleClientRequestInitializer(new GoogleClientRequestInitializer() {
@Override
public void initialize(AbstractGoogleClientRequest<?> abstractGoogleClientRequest) throws IOException {
abstractGoogleClientRequest.setDisableGZipContent(true);
}
});
// end options for devappserver

myApiService = builder.build();
}

try {
return myApiService.listQuote().execute().getItems();
} catch (IOException e) {
return Collections.EMPTY_LIST;
}
}

@Override
protected void onPostExecute(List<Quote> result) {
for (Quote q : result) {
Toast.makeText(context, q.getWho() + " : " + q.getWhat(), Toast.LENGTH_LONG).show();
}
}
}

Let us go through the code in brief:

  1. This is a standard Android Async Task.
  2. Notice that since everything is all integrated inside of Android Studio, we simply imported the classes via the com.mindstorm.api.quoteEndpoint packages.
  3. An instance of the QuoteEndpoint is built via the builder as shown. Here we specify the HTTP Transport, JSON Factory and since there is currently no authentication stuff, the 3rd parameter is null. Since we are testing it locally , we are providing 10.0.2.2 which is the localhost for an Application that is run on the Android Emulator.
  4. Once the QuoteEndpoint service instance is available, we can invoke one of the various methods that it exposes like listQuotes, insertQuote, removeQuote, updateQuote, etc.
  5. Notice that the Cloud Endpoints client libraries behind the scenes do the marshalling/unmarshalling for us between Java objects and JSON data format and we get the response via our Java objects. In this case, we get back a list collection of Quote objects.

That is all really to it. You should try out writing other Async Tasks for more methods, so that you can familiar with this pattern.

In terms of authentication, I do not think anything changes just because it is Android Studio. You should read up on the Authentication episodes that I have covered earlier as part of my Cloud Endpoints tutorials, should you need to add security to your Endpoints.

Few Gotchas

  1. Remember to start the api application i.e. run the Local Development Server before your run your Android application.
  2. Always test out your Endpoints via the Local API Explorer before starting off with Android Development.
  3. Remember that 10.0.2.2 is the localhost’s IP Address in the Android emulator.
  4. If you deploy your Endpoints to App Engine live environment, do remember to change those settings with the actual deployed application id.
  5. Important: Do read up on the App Engine Java Endpoints Module template. It will provide you with the Async Task template that you will need to use in your Android code to invoke the Endpoint services.

Moving forward

With this episode, I do believe we have come to some sort of a logical end in our journey, since we are doing less of Gradle and more of Android + Endpoints stuff in the last few episodes, but that is ok.

Hopefully, the series has helped you understand better the different files that are getting generated vis-a-vis the Gradle stuff.

I do think I will do an episode or two more, to cover a multi-module project with Android wear too.

All the best for your projects!

Posted in Tools | 8 Comments

Gradle Tutorial : Part 9 : Cloud Endpoints + Persistence + Android Studio

Welcome to Part 9 of the Gradle Tutorial. In the previous episode i.e. Part 8, we looked at support for Cloud Endpoints in your Android Project and how it can form the basis for your mobile backend. Our focus in that part was to understand the mechanics of Cloud Endpoints inside Android Studio, testing out our API via the local API Explorer and so on.

This part of the tutorial is an extension of Part 8, maybe I should have called it Part 8 – Part II :-) but I am keeping it separate here so that we can focus on what it is meant to do i.e. address Persistence using Objectify in your Cloud Endpoitns.

For those of you, who are not aware of Cloud Endpoints, I strongly recommend going through a couple of my blog posts, where I have covered the premise for Cloud Endpoints and Cloud Endpoints basics in the first two parts of my Cloud Endpoints blog series. They are present here : Part 1 and Part 2.

ep8-logo

This part assumes that you have installed Android Studio on your development machine and that you are familiar with basic Gradle commands, project structure and files as we have seen in the series so far.

I have used Android Studio (Beta) 0.8.6 on Windows for this blog post. It is not necessary to have the same version or the OS, things should be pretty much similar from a Gradle perspective.

We shall cover the following in this blog post:

  • Begin with a default Android application in Android Studio. Add an App Engine module to the Android Project. This part is the same as Part 8, so I will only mention the steps without putting in any screen shots. 
  • We are going to be using Objectify, a library that makes the task of adding persistence to your App Engine applications, as simple as it can get. Behind that simplicity is some serious piece of work, so a big thank you to the developer of Objectify.
  • We then develop a Quote Endpoint service, a simple service that allows us to manage Quotes by famous people. We shall look at methods to add, modify, delete and list Quotes and it will be backed with a persistent layer powered by Objectify.
  • We shall study the code in the Endpoints, test it out and also understand the additional gradle build dependency needed for Objectify.

Android Application

Allright, I believe you know the process now to generate an Android Application inside of Android Studio, so I will not give too many details like screen shots. Let me state the steps again and please follow along in Android Studio:

  1. Click on New Project in the Quick Launch dialog. This should bring up the New Project wizard. Give it a name and company domain.
  2. Click on Next and keep following all the default stuff till you Finish.

Be a bit patient and let your Android project build successfully.

Add an App Engine Module

Now that we have an Android project and an Android app module within the project i.e. app, let us move forward and make this a multi-module project by adding an App Engine module to this project.

To add a new module to your project, simply select File –> New Module. This will bring up the dialog as shown below:

s6
 Make sure you select the App Engine Java Endpoints Module. 

Click on Next to proceed. This brings up a dialog where you should specify your module app. I am naming it api and I give it a package name for my Java code that would reside in there.

s7

Click on Finish to generate the project. You should now have two modules in your project i.e. app (Android) and api (App Engine).

Gradle Files

If you are new to Gradle, I suggest following my earlier episodes, but for now, the only thing we are going to look at now is the build.gradle file in the api module.

The reason for that is that we are going to use Objectify for our persistene code and it is an external library.

The relevant section from api/build.gradle file is shown below:

api module – build.gradle

The api/build.gradle file is shown below:

...

dependencies {
 appengineSdk 'com.google.appengine:appengine-java-sdk:1.9.6'
 compile 'com.google.appengine:appengine-endpoints:1.9.6'
 compile 'com.google.appengine:appengine-endpoints-deps:1.9.6
 compile 'com.googlecode.objectify:objectify:5.0.3'
 compile 'javax.servlet:servlet-api:2.5'
}
...

All we have done is added the objectify dependency to our build.gradle file. We are using the latest version of the library.

That’s about it really as far as the Gradle stuff is concerned.

Tip: Keep in mind that anytime you make any changes to your build files, do remember to click on the Sync Project with Gradle Files as shown below. It should launch the build and you should be able to see the Gradle commands getting executed in the Gradle Console.

Please do this, so that the Objectify dependency is downloaded to your local repository and you are all set!

gradle-ep6-11

Cloud Endpoints – Understand the files

This section assumes that you are familiar with to some extent with Google Cloud Endpoints in Java. I recommend going through Part 1 and Part 2 of my tutorials on End points, if you are absolutely new to Endpoints.

By default only the MyBean and MyEndpoint files would be generated for you. We saw that in the previous episode and you can ignore them for now, since we will be generating a new Endpoint class on our own. 

The model that we shall be managing here is a simple Quote object. A Quote is a famous saying by a person and we are going to keep it simple. It will have 3 attributes:

  • Id : This will be a unique value for the record when it is persistent in the Datastore.
  • Who : This is the name of the person who said the quote i.e. to whom the quote is attributed.
  • What : The text of the Quote.

So technically, we shall have at least 2 files i.e. the Quote.java file, which will be the Java Bean with some annotations for persistence and the QuoteEndpoint.java file, which will have the Endpoint specific code with all its annotations.

Additionally, we may have our other support files as needed.  Remember that I have created all these Java classes in the following path :
- api/src/main/java/<package-name>

Let us look at the source code now.

Quote.java


package com.mindstorm.api;

import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id;

@Entity
public class Quote {
 @Id
 Long id;
 String who;
 String what;

public Quote() {}

public Long getId() {
 return id;
 }

public void setId(Long id) {
 this.id = id;
 }

public String getWho() {
 return who;
 }

public void setWho(String who) {
 this.who = who;
 }

public String getWhat() {
 return what;
 }

public void setWhat(String what) {
 this.what = what;
 }
}

Let us look at the important points in the above code:

  • It is a standard bean and you can see our 3 attributes i.e. id, who and what.
  • Two annotations are important from an Objectify perspective. We need to mention to Objectify that this is an entity that needs to be persisted, there is the @Entity annotation for that and we have it right at the top at the class level.
  • Additionally, we are specifying the @Id attribute for the attribute that is the identifier.

This should suffice for us. Do note that you should definitely study the Objectify documentation for more of the annotation stuff.

QuoteEndpoint.java


package com.mindstorm.api;

import com.google.api.server.spi.config.Api;
import com.google.api.server.spi.config.ApiMethod;
import com.google.api.server.spi.config.ApiNamespace;
import com.google.api.server.spi.config.Nullable;
import com.google.api.server.spi.response.CollectionResponse;
import com.google.api.server.spi.response.ConflictException;
import com.google.api.server.spi.response.NotFoundException;
import com.google.appengine.api.datastore.Cursor;
import com.google.appengine.api.datastore.QueryResultIterator;
import com.googlecode.objectify.cmd.Query;

import static com.mindstorm.api.OfyService.ofy;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

import javax.inject.Named;

@Api(name = "quoteEndpoint", version = "v1", namespace = @ApiNamespace(ownerDomain = "api.mindstorm.com", ownerName = "api.mindstorm.com", packagePath=""))
public class QuoteEndpoint {

// Make sure to add this endpoint to your web.xml file if this is a web application.

public QuoteEndpoint() {

}

/**
* Return a collection of quotes
*
* @param count The number of quotes
* @return a list of Quotes
*/
@ApiMethod(name = "listQuote")
public CollectionResponse<Quote> listQuote(@Nullable @Named("cursor") String cursorString,
@Nullable @Named("count") Integer count) {

Query<Quote> query = ofy().load().type(Quote.class);
if (count != null) query.limit(count);
if (cursorString != null && cursorString != "") {
query = query.startAt(Cursor.fromWebSafeString(cursorString));
}

List<Quote> records = new ArrayList<Quote>();
QueryResultIterator<Quote> iterator = query.iterator();
int num = 0;
while (iterator.hasNext()) {
records.add(iterator.next());
if (count != null) {
num++;
if (num == count) break;
}
}

//Find the next cursor
if (cursorString != null && cursorString != "") {
Cursor cursor = iterator.getCursor();
if (cursor != null) {
cursorString = cursor.toWebSafeString();
}
}
return CollectionResponse.<Quote>builder().setItems(records).setNextPageToken(cursorString).build();
}

/**
* This inserts a new <code>Quote</code> object.
* @param quote The object to be added.
* @return The object to be added.
*/
@ApiMethod(name = "insertQuote")
public Quote insertQuote(Quote quote) throws ConflictException {
//If if is not null, then check if it exists. If yes, throw an Exception
//that it is already present
if (quote.getId() != null) {
if (findRecord(quote.getId()) != null) {
throw new ConflictException("Object already exists");
}
}
//Since our @Id field is a Long, Objectify will generate a unique value for us
//when we use put
ofy().save().entity(quote).now();
return quote;
}

/**
* This updates an existing <code>Quote</code> object.
* @param quote The object to be added.
* @return The object to be updated.
*/
@ApiMethod(name = "updateQuote")
public Quote updateQuote(Quote quote)throws NotFoundException {
if (findRecord(quote.getId()) == null) {
throw new NotFoundException("Quote Record does not exist");
}
ofy().save().entity(quote).now();
return quote;
}

/**
* This deletes an existing <code>Quote</code> object.
* @param id The id of the object to be deleted.
*/
@ApiMethod(name = "removeQuote")
public void removeQuote(@Named("id") Long id) throws NotFoundException {
Quote record = findRecord(id);
if(record == null) {
throw new NotFoundException("Quote Record does not exist");
}
ofy().delete().entity(record).now();
}

//Private method to retrieve a <code>Quote</code> record
private Quote findRecord(Long id) {
return ofy().load().type(Quote.class).id(id).now();
//or return ofy().load().type(Quote.class).filter("id",id).first.now();
}

}

This is our main Endpoint class. Note that this class is not being generated currently by Android Studio. So do not expect that you will simply provide the annotations and Android Studio will be able to generate it for now. I do expect that in future versions, all this will be addressed with much more solid code but for now, this should give you a flavor for how easy Objectify makes it to add persistence to your code.

Let us understand what is going on in the code:

  1. We want to provide an Endpoints layer for our Quote object. And that is what this class QuoteEndpoint.java is all about.
  2. We plan to have methods to add, modify, list and delete Quote objects. Hence you see those methods implemented.
  3. We are using the annotation @Api at the class level to mark this as an Endpoint class. The name is quoteEndpoint.
  4. Each of the methods is annotated with the @Apimethod annotation and we provide the method name via the name attribute.
  5. Objectify code is beautifully summarized by a snippet shown in the original documentation, which I reproduce here. Just look at the pattern for Add, Get and Delete operations and you will understand it.ep9-1
  6. In the insertQuote method, we are first checking if a record exists in the database with the same id. If it exists, pay close attention to the Exception that we are throwing. These are standard Exceptions available in the Endpoint package and you should throw them, so that the correct HTTP Code is returned in the response too. If the record is not present, we go ahead and save the entity that was passed. Since it is a Long type, Objectify will generate the id for us automatically. The now() is the synchronous nature of the call, where we want it to execute immediately. The ofy() is a static object that is a handle to the Objectify Service and that utility class is covered in the next section.
  7. Similarly, take a look at updateQuote and deleteQuote methods. It should be straight forward.
  8. The last method that I want to touch up here is the listQuote API method. I have tried to reproduce this as much as I could from the way the code was generated by the Eclipse plugin for JDO supported code earlier. For those of you from the JDO Endpoints world of Eclipse, this will look similar. For those of you not familiar with that, don’t worry.
  9. The listQuote method supports optional parameters where you can provide a count i.e. number of records you want and in subsequent calls, you can even give the cursor from where it should give the next set of records. The rest of the code is standard Objectify code for querying the object, iterating through the number of records required, putting them in a list to return and remembering to set the cursor in case the client wants to make subsequent calls.

That’s about it for our Endpoint. Spend some time with the code and Objectify documentation and you will understand things better. Or just use my code as a rough template for your own Endpoint classes.

OfyService.java


package com.mindstorm.api;

import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyFactory;
import com.googlecode.objectify.ObjectifyService;

/**
 * Objectify service wrapper so we can statically register our persistence classes
 * More on Objectify here : https://code.google.com/p/objectify-appengine/
 *
 */
public class OfyService {

static {
 ObjectifyService.register(Quote.class);
 }

public static Objectify ofy() {
 return ObjectifyService.ofy();
 }

public static ObjectifyFactory factory() {
 return ObjectifyService.factory();
 }
}

This is a utility class that we have written that provides an instance to the Objectify service i.e. the ofy() object that you saw earlier in the Endpoint code. One important thing is that you need to tell Objectify which Entity objects it can deal with i.e. you have to register them upfront. We are registering our Quote entity via the line 

 ObjectifyService.register(Quote.class);

In case you have other endpoint classes in your module, please remember to register those in the ObjectifyService.java class too.

Endpoints in Action

This should standard stuff now i.e. running the local App Enging Development Server.

Important

Before you jump right ahead and try to launch the Dev App Server, remember the point we made in the last episode that there is a minor bug in Android Studio, where it does not add the Endpoints class to the web.xml file. 

Visit the api/src/main/webapp/WEB-INF/web.xml file and add the QuoteEndpoint class as shown below:

s18

Follow the next steps to launch the local development server:

  1. Launch a Terminal window as shown below. Navigate to the root folder and then fire the gradle command as shown below. Do note that we are simply starting up the App Engine Local Dev Server here via the appengineRun task. We are prefixing it with the module name i.e. api , since we are at the root and we need to specify which module and Gradle Task inside of that, which we are interested in firing.s22
  2. Once the server is started, you should see the a message saying that the local server is running as shown below:

s23

Once the Local Dev Server is started, go ahead and visit the local dev server at localhost:8080 URL via browser as shown below.

s8

We need to now access the local API Explorer that will help us test out the functionality of our Quote Endpoint class.

Typically, this is accessible via http://localhost:8080/_ah/api in your browser. You could either type that out or you can click on the Google Cloud Endpoints API Explorer as shown below:

s10

Click that and it should bring up the API Explorer as shown below. Make sure you are connected to the Internet.

ep9-2

The above screen indicates that you have two Endpoint APIs, the default MyAPI if you have not removed the default one and also our quoteEndpoint API:

Click on the quoteEndpoint API to see the different methods that we had exposed. You should see all the methods listed as shown below:

ep9-3

Click on the quoteEndpoint.insertQuote method. This will bring up a form where you can test out the API:

ep9-4

Notice how the API Explorer is able to introspect your method parameters and provide you a convenient HTML form, where you can enter your parameter values. Enter some values (for who and what attributes, leave the id field blank since it will be autogenerated) and click on Execute. This will invoke your API, and show you the request / response details as given below:

ep9-5

Similarly do try out other methods i.e. listQuote, removeQuote .. and it should all work. If you are looking to understand the count and cursor parameters, do refer to this tip : Using Cursor and Limit Parameters, that I wrote.

In case you want to check if the records have been persisted in the local datastore, you can visit the local Admin app via http://localhost:8080/_ah/admin URL. Visit the Datastore Viewer link and you should see your Entity (Quote) and the various records there.

ep9-7

Here is a screenshot from the listQuote execution:

ep9-6

Moving forward

This tutorial helped you understand writing real Endpoint classes which implement persistence. Specifically, we looked at Objectify library to build in persistence support.

In the next episode, we shall look at integrating the Endpoints code into our Android project.

Till then, Happy Gradling! or should I say “Happy Cloud Endpoints Generation”!

Posted in Tools | 4 Comments

Gradle Tutorial : Part 8 : Gradle + App Engine + Endpoints + Android Studio

Welcome to Part 8 of the Gradle Tutorial. In the previous episode i.e. Part 7, we looked at a multi-module Android project inside Android Studio. The multi-module Android project had an Android module and an App Engine module. The App Engine module was a basic one with a simple Servlet + JSP.

In this part of the tutorial, we are going to look at another multi-module Android project in Android Studio, except that instead of the basic App Engine project, we are going to look at Cloud Endpoints support inside of Android Studio. This episode and an episode or two following this one, shall expand on Cloud Endpoints but in this episode, we will keep things simple and look at the Endpoints basics inside of Android Studio.

For those of you, who are not aware of Cloud Endpoints, I strongly recommend going through a couple of my blog posts, where I have covered the premise for Cloud Endpoints and Cloud Endpoints basics in the first two parts of my Cloud Endpoints blog series. They are present here : Part 1 and Part 2.

This tutorial is not a deep dive into what Cloud Endpoints is, what it brings to the table and so on. My assumption is that you are familiar with the concept, have written an Endpoint or two in Java and have primarily used the Eclipse plugin for GAE and now want to see how it is similarly supported in Android Studio.

In summary, Google Cloud Endpoints is a great way to add a mobile backend to your applications. And its integration and support inside of Android Studio is a good confirmation of the fact, that support for it inside of Android Studio is going to grow and get better. It might have its few issues in the initial versions but it is also a great time to get going with it in Android Studio. 

ep8-logo

This part assumes that you have installed Android Studio on your development machine and that you are familiar with basic Gradle commands, project structure and files as we have seen in the series so far.

I have used Android Studio (Beta) 0.8.6 on Windows for this blog post. It is not necessary to have the same version or the OS, things should be pretty much similar from a Gradle perspective.

The areas that we shall cover in this blog post are as follows:

  • Begin with a default Android application in Android Studio.
  • Add an App Engine module to the Android Project i.e. convert the Android Project into a multi-module project i.e. Android App and App Engine App. In the App Engine module for this episode, we shall go with the Endpoints module.
  • Study the Gradle files for the multi-module project that we now have.
  • Understand the sample Endpoint generated, look at adding your own Endpoint (minimal) and see what default code is generated by Android Studio to help you with your Endpoint code.

Android Application

Allright, lets go ahead and create/generate our Android Application. We are going to be using the Android Studio Wizard to do that. Nothing fancy.

Click on New Project in the Quick Launch dialog. This should bring up the New Project wizard as shown below. I have stuck to tradition and called my project HelloCloudEndpoints :-)

s1

Just take all the defaults as shown in the next screens for the wizard.

gradle-ep6-5

gradle-ep6-6

gradle-ep6-7

Click on Finish to end the wizard and then it weaves some magic to generate the Android Studio project files for you. Be a bit patient.

Add an App Engine Module

Now that we have an Android project and an Android app module within the project i.e. app, let us move forward and make this a multi-module project by adding an App Engine module to this project.

To add a new module to your project, simply select File –> New Module. This will bring up the dialog as shown below:

s6
You will see several modules that you can add to your existing project. Three of these modules are specific to App Engine and you can see them in the list. Since we are going to be covering the Java Endpoints in this episode, select the App Engine Java Endpoints Module. 

Click on Next to proceed. This brings up a dialog where you should specify your module app. I am naming it api and I give it a package name for my Java code that would reside in there.

s7

Click on Finish to generate the project. Once the project is generated, you will find that you have now an additional module named api in the Project hierarchy as shown below:

s21

You will also notice that you can now Run both the Android App and the App Engine if you want to.

s20

Gradle Files

In Part 3, we had covered multiple Java projects and how at the root folder, we can specify the settings.gradle and build.gradle files that apply across all the modules.

Let us recap, what we have so far:

  • We have an Android Studio Project
  • It has 2 modules
  • One module (app) is the Android app
  • One module (api) is the App Engine app

So, let us look at the settings.gradle file at the root:

include ':app', ':api'

It includes now both the app module and the api module, which is how we had seen in Part 3 of this series.

The build.gradle files at the root folder is the same as we had seen in the previous episode, so I am not repeating here.

app module – build.gradle

This file is the same as the previous episode, except for one important difference. 

As you know, Endpoints provides a backend for your mobile application and it does that by providing a standards-based REST API that exposes your backend functionality, such that it can be invoked from the Android application. We shall see in a later episode as to how to integrate this API i.e. Endpoints code into your Android application.

For now, what is important to note is that Android Studio assumes that since your app module (Android app) depends on the api module (App Engine Endpoints app), it puts that dependency into the build.gradle file for the app module. The relevant part from the dependencies section is shown below:

...

dependencies { 
 compile fileTree(dir: 'libs', include: ['*.jar'])
 compile project(path: ':api', configuration: 'android-endpoints')
}

...

We had learnt this stuff in Part 3, where we had look at multi module Java projects and how you can place the dependencies on each other in the build.gradle file. The above highlighted line simply states that to compile app module successfully, we have to first compile / build the api module. And which makes sense, doesn’t it ?

api module – build.gradle

Let us now, step inside of the api module. There you will find the module specific build.gradle that is shown below. Remember, this one is an App Engine application, so it will utilize the App Engine plugin. We had seen a similar looking build.gradle file in Part 5 of the series.

The api/build.gradle file is shown below:

// Currently, the appengine gradle plugin's appengine devappserver launch doesn't interact well with Intellij/AndroidStudio's
// Gradle integration. As a temporary solution, please launch from the command line.
// ./gradlew modulename:appengineRun
// If you would like more information on the gradle-appengine-plugin please refer to the github page
// https://github.com/GoogleCloudPlatform/gradle-appengine-plugin

buildscript {
 repositories {
 mavenCentral()
 }
 dependencies {
 classpath 'com.google.appengine:gradle-appengine-plugin:1.9.6'
 }
}

repositories {
 mavenCentral();
}

apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'appengine'

sourceCompatibility = 1.7
targetCompatibility = 1.7

dependencies {
 appengineSdk 'com.google.appengine:appengine-java-sdk:1.9.6'
 compile 'com.google.appengine:appengine-endpoints:1.9.6'
 compile 'com.google.appengine:appengine-endpoints-deps:1.9.6'
 compile 'javax.servlet:servlet-api:2.5'
}

appengine {
 downloadSdk = true
 appcfg {
 oauth2 = true
 }
 
 endpoints {
  getClientLibsOnBuild = true
  getDiscoveryDocsOnBuild = true
 }

}

Some of the important points are:

  • Take a look at dependencies closure that we have seen earlier. It includes the App Engine SDK 1.9.6 and also the Servlet jar and in addition to that, it also includes the endpoint JARs. This is needed so that we can compile/build/run endpoints related code and all the annotations that are endpoints specific can be found.
  • In the appengine closure, you will notice another closure aptly titled endpoints that is in addition to the previous code. These attributes, when set to true, automatically download the Client Libraries and the Discovery Docs before the war task is called. Refer to the official documentation on the Gradle App Engine plugin.

That’s about it really as far as the Gradle stuff is concerned.

Tip: Keep in mind that anytime you make any changes to your build files, do remember to click on the Sync Project with Gradle Files as shown below. It should launch the build and you should be able to see the Gradle commands getting executed in the Gradle Console.

gradle-ep6-11

Cloud Endpoints – Understand the files

This section assumes that you are familiar with some extend with Google Cloud Endpoints in Java. I recommend going through Part 1 and Part 2 of my tutorials on End points, if you are absolutely new to Endpoints.

MyBean.java

This is the default Object Model generated when you use the add a Cloud Endpoints module to your Android Studio project. The MyBean.java is not much and I would have liked to see something more than this, but it suffices for the sake of understanding here.


package com.mindstorm.api;

/** The object model for the data we are sending through endpoints */
public class MyBean {

private String myData;

public String getData() {
 return myData;
 }

public void setData(String data) {
 myData = data;
 }
}

MyEndpoint.java

This is the Endpoint class and it exposes some of the operations around the MyBean model that we just saw. The code is listed below:


package com.mindstorm.api;

import com.google.api.server.spi.config.Api;
import com.google.api.server.spi.config.ApiMethod;
import com.google.api.server.spi.config.ApiNamespace;

import javax.inject.Named;

/** An endpoint class we are exposing */
@Api(name = "myApi", version = "v1", namespace = @ApiNamespace(ownerDomain = "api.mindstorm.com", ownerName = "api.mindstorm.com", packagePath=""))
public class MyEndpoint {

/** A simple endpoint method that takes a name and says Hi back */
 @ApiMethod(name = "sayHi")
 public MyBean sayHi(@Named("name") String name) {
 MyBean response = new MyBean();
 response.setData("Hi, " + name);

return response;
 }

}

If you are familiar with Cloud Java Endpoints, here are the main points:

  • The @Api annotation marks the class as an Endpoint. Its name is myApi and it has been given a version v1
  • The method sayHi has been exposed as one of the Endpoints methods. The name of the API is sayHi as per the annotation @ApiMethod and the name attribute. There is nothing much happening in the code other than instantiating the bean and returning the bean. Do note that this episode will keep things simple and in a subsequent episode, we shall see persistent data and a lot more methods. 

Endpoints in Action

Let us see how to run and test out the Endpoints so far inside of Android Studio. I prefer giving you instructions via the Terminal, so that you can use the Gradle Tasks.

  1. Launch a Terminal window as shown below. Navigate to the root folder and then fire the gradle command as shown below. Do note that we are simply starting up the App Engine Local Dev Server here via the appengineRun task. We are prefixing it with the module name i.e. api , since we are at the root and we need to specify which module and Gradle Task inside of that, which we are interested in firing.s22
  2. Once the server is started, you should see the a message saying that the local server is running as shown below:

s23

Once the Local Dev Server is started, go ahead and visit the local dev server at localhost:8080 URL via browser as shown below.

s8

Enter some text and click on Say Hello, it should all work fine:

s9

The next thing that you should do is check out the Endpoints Explorer. As mentioned earlier, Google Cloud Endpoints provides a REST Endpoint that exposes your functionality. In our case, it is the MyBean with the Endpoint that exposes a single method sayHi.

Typically, this is accessible via http://localhost:8080/_ah/api in your browser. You could either type that out or you can click on the Google Cloud Endpoints API Explorer as shown below:

s10

Click that and it should bring up the API Explorer as shown below. Make sure you are connected to the Internet.

s11

The above screen indicates that you have an API, whose name we had seen earlier MyAPI with version 1.0. Click on the MyAPI API and it will display you the available methods that you can invoke as shown below:

s12

Click on the MyAPI.sayHi method. This will bring up a form where you can test out the API:

s13

Notice how the API Explorer is able to introspect your method parameters and provide you a convenient HTML form, where you can enter your parameter values. Enter some value and click on Execute. This will invoke your API, and show you the request / response details as given below:

s14

For those coming from the Eclipse + Cloud Endpoints world, this should all be familiar.

Add a new Endpoint API

Let us now look at adding our own Java class and creating an Endpoint around it. Though it is not going to be too different that the one (MyBean) that was generated for us, it is important to look at the tools available and I wanted to also show you a bug that I came across.

Let us add our own Bean class that we want to expose as an Endpoint. The class is a simple Quote.java class as shown below:

Quote.java


package com.mindstorm.api;

/**
 * Created by irani_r on 8/25/2014.
 */
public class Quote {
 Long id;
 String who;
 String whom;

public Long getId() {
 return id;
 }

public void setId(Long id) {
 this.id = id;
 }

public String getWho() {
 return who;
 }

public void setWho(String who) {
 this.who = who;
 }

public String getWhom() {
 return whom;
 }

public void setWhom(String whom) {
 this.whom = whom;
 }
}

You can create the above class via the File -> New -> Java class option. Make sure that you place the file in the api module inside the src/main/java and the respective package file.

Now, just like in Eclipse, you can use one of the Code Generation options that is available in Android Studio also. Simple select the Java file i.e. Quote.java and then select Tools -> Google Cloud Tools -> Generate Endpoint as shown below:

s15

 

This will generate the QuoteEndpoint.java class as shown below:

QuoteEndpoint.java


package com.mindstorm.api;

import com.google.api.server.spi.config.Api;
import com.google.api.server.spi.config.ApiMethod;
import com.google.api.server.spi.config.ApiNamespace;

import java.util.logging.Logger;

import javax.inject.Named;

/** An endpoint class we are exposing */
@Api(name = "quoteEndpoint", version = "v1", namespace = @ApiNamespace(ownerDomain = "api.mindstorm.com", ownerName = "api.mindstorm.com", packagePath=""))
public class QuoteEndpoint {

// Make sure to add this endpoint to your web.xml file if this is a web application.

private static final Logger LOG = Logger.getLogger(QuoteEndpoint.class.getName());

/**
 * This method gets the <code>Quote</code> object associated with the specified <code>id</code>.
 * @param id The id of the object to be returned.
 * @return The <code>Quote</code> associated with <code>id</code>.
 */
 @ApiMethod(name = "getQuote")
 public Quote getQuote(@Named("id") Long id) {
 // Implement this function

LOG.info("Calling getQuote method");
 return null;
 }

/**
 * This inserts a new <code>Quote</code> object.
 * @param quote The object to be added.
 * @return The object to be added.
 */
 @ApiMethod(name = "insertQuote")
 public Quote insertQuote(Quote quote) {
 // Implement this function

LOG.info("Calling insertQuote method");
 return quote;
 }
}

The code that is generated is not something you want to put into production and I am sure that it will improve over time. But it gives you 2 methods getQuote and insertQuote as shown above. Notice that the appropriate @API Annotation (the API name is quoteEndpoint)  is added to the QuoteEndpoint.java class.

While this looks good at the surface, you will find that if you restart the Local Dev Server and go to API Explorer, the new Endpoint (quoteEndpoint) is not available in the list. This is because the Code Generator for the Endpoint class missed out on adding a critical entry to the web.xml file.

To add the new Endpoint class to the Endpoint library when it is starting up, go to the web.xml file for the api module as shown below:

s16

You will notice that the entry shown below has only the default MyEndpoint class as shown below. It should ideally have a comma separated list of all Endpoint classes i.e. all classes that are annotated with the @API annotation.

s17

Go ahead and add the entry for our QuoteEndpoint as given below. Remember to use the full package name for the class.

s18

Save the above file. Restart the Dev Server and then navigate over to the API Explorer, you will be able to see both the API Endpoints now and if you navigate to the quoteEndpoint API, you will see both the methods as listed below:

s19

Deploying the API Module to App Engine

So far we have seen the Endpoints module (api) running locally. If you want to deploy the module to App Engine, you will need to do the following steps:

  1. Create a Project via the Cloud Console and note down the Project Id. If you already have a project that you wish to deploy into, then you just need the Project Id.
  2. Go to api/src/main/webapp/WEB-INF/appengine-web.xml file. Provide your Project Id in the <application> element. Save the file.
  3. Go to api/build.gradle and modify the appengine closure as shown below (Note the items in bold:
     appengine {
        downloadSdk = true
    
        appcfg {
           oauth2 = true
           noCookies = true
           email = "<Your Google Account Email Address>"
        }
    
     endpoints {
       getClientLibsOnBuild = true
       getDiscoveryDocsOnBuild = true
     }
    }
  4. Now go to the Terminal and from the root folder, fire the following Gradle command:gradlew api:appengineUpdateThe steps are similar to the ones that we saw in Part 5, where we covered how the OAuth process will kick in for authentication and how you need to paste the verification code, etc.
  5. The terminal should show a flurry of log statements after which the app will be deployed.
  6. You should visit the Cloud Console to confirm if the app is ready. Additionally, you can access the API explorer via the following URL :
    http://yourprojectid.appspot.com/_ah/api/explorer.Note that we have simply replaced the localhost:port with yourprojectid.appspot.com

Moving forward

This tutorial helped you understand support for Google Cloud Endpoints module in a multi-module Android project within Android Studio.

Cloud Endpoints is a vast topic and the next 1-2 episodes will focus on adding persistence to your Cloud Endpoints and how to invoke your Cloud Endpoints code from Android app. Well that is the main point since we generated the Android Studio project with the Android app, adding a Cloud Endpoints module and so we better be able to call the Endpoints API from the Android app ! :-)

Till then, Happy Gradling!

Posted in Tools | 4 Comments

Gradle Tutorial : Part 7 : Android Studio + App Engine + Gradle

Welcome to Part 7 of the Gradle Tutorial. In the previous episode i.e. Part 6, we took a first look at understanding the Gradle build files that are generated for a basic Android application inside of Android Studio.

In this part of the tutorial, we shall expand on what we did in the last episode. We will continue to be with our basic Android application that has been generated in Android Studio. In addition, we are going to look at adding another module to this Android project. In other words, we are going to take a look at multi-module Java project inside of Android Studio and our knowledge from Part 3, where we loooked at multi-module Java projects will help us.

We look at App Engine Gradle plugin in Part 5 and in this episode, the second module that we shall be adding to our Android Project will be an App Engine module. Yes, you read that right. Android Studio has started to get good support for App Engine projects, such that if you are looking at writing a backend for your Android Application, this can be a great choice and you can do all of that inside of Android Studio.

Our goal in this episode will only be to familiarize ourselves with an Android Project in Android Studio that has 2 modules : Android App and the App Engine App. This is not an tutorial for learning, either Android or App Engine.

gradle

This part assumes that you have installed Android Studio on your development machine and that you are familiar with basic Gradle commands, project structure and files as we have seen in the series so far.

I have used Android Studio (Beta) 0.8.6 on Windows for this blog post. It is not necessary to have the same version or the OS, things should be pretty much similar from a Gradle perspective.

The areas that we shall cover in this blog post are as follows:

  • Begin with a default Android application in Android Studio. We shall not cover the basics of the gradle files for this. We saw that in the previous episode i.e. Part 6. Please read that.
  • Add an App Engine module to the Android Project i.e. convert the Android Project into a multi-module project i.e. Android App and App Engine App
  • Study the Gradle files for the multi-module project that we now have
  • Cover some basic operations of dealing with App Engine within Android Studio. This is the Android Studio version of the stuff that we tried out via the App Engine Gradle plugin in Part 5.

Android Application

Allright, lets go ahead and create/generate our Android Application. We are going to be using the Android Studio Wizard to do that. Nothing fancy.

Click on New Project in the Quick Launch dialog. This should bring up the New Project wizard as shown below. I have stuck to tradition and called my project HelloWorldAndroid :-)

gradle-ep6-4

Just take all the defaults as shown in the next screens for the wizard.

gradle-ep6-5

gradle-ep6-6

gradle-ep6-7

Click on Finish to end the wizard and then it weaves some magic to generate the Android Studio project files for you. Be a bit patient.

Add an App Engine Module

Now that we have an Android project and an Android app module within the project i.e. app, let us move forward and make this a multi-module project by adding an App Engine module to this project.

To add a new module to your project, simply select File –> New Module. This will bring up the dialog as shown below:

ep7-1You will see several modules that you can add to your existing project. Three of these modules are specific to App Engine and you can see them in the list. For now, we shall just take the most basic one i.e. App Engine Java Servlet Module as shown above.

This is the same basic template that you would have got if you were using Eclipse and had generated a new Web Application using the Google Eclipse plugin. 

Click on Next to proceed. This brings up a dialog where you should specify your module app. I am naming it serverapp and I give it a package name for my Java code that would reside in there.

ep7-2

Click on Finish to generate the project. Once the project is generated, you will find that you have now an additional module named serverapp in the Project hierarchy as shown below:

ep7-4

You will also notice that you can now Run both the Android App and the App Engine if you want to. Just check out the Run option as shown below:

ep7-6

Gradle Files

In Part 3, we had covered multiple Java projects and how at the root folder, we can specify the settings.gradle and build.gradle files that apply across all the modules.

Let us recap, what we have so far:

  • We have an Android Studio Project
  • It has 2 modules
  • One module (app) is the Android app
  • One module (serverapp) is the App Engine app

So, let us look at the settings.gradle file at the root:

include ':app', ':serverapp'

It includes now both the app module and the serverapp module, which is how we had seen in Part 3 of this series.

Take a look at the build.gradle file at the root:

// Top-level build file where you can add configuration options 
// common to all sub-projects/modules.

buildscript {
 repositories {
   jcenter()
 }

dependencies {
 classpath 'com.android.tools.build:gradle:0.12.2'

// NOTE: Do not place your application dependencies here; they 
// belong in the individual module build.gradle files
 }
}

allprojects {
  repositories {
    jcenter()
  }
}

No surprises here. This should be understandable too. For allprojects, we are specifying the repository to be used. JCenter is another repository similar to MavenCentral that we had seen earlier. Additionally, we had seen in the earlier episode, how buildscript can be used to specify what is going to be needed to run the script itself. At that time, we had included the App Engine Plugin/SDK and now we have the Gradle library for the Android Tools Project.

app module – build.gradle

This section is a repeat from the previous episode:

Let us now, step inside of the app module. There you will find the module specific build.gradle that is shown below. Remember it is an Android app, so it will utilize the Android plugin and have Android plugin specific closures that make sense when compiling, building , running, packaging the Android application.

The app/build.gradle file is shown below:

apply plugin: 'com.android.application'

android {
  compileSdkVersion 20
  buildToolsVersion "20.0.0"

  defaultConfig {
     applicationId "com.mindstorm.helloworldandroid"
     minSdkVersion 19
     targetSdkVersion 20
     versionCode 1
     versionName "1.0"
  }

  buildTypes {
    release {
      runProguard false
      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
      }
    }
 }

dependencies {
 compile fileTree(dir: 'libs', include: ['*.jar'])
}

Some of the important points are:

  • We specify the use of the Android plugin via the apply plugin command
  • Take a look at dependencies closure that we have seen earlier. Currently it simply adds all the JAR Files that you might add to the libs folder. Alternately, you can also add more of your dependencies here as we have seen earlier.
  • The android closure is a standard one that is used for specifying which SDK version to use for compiling, the minimum SDK Version supported, package name, versioning information and pro Guard related stuff. If you have built Android applications, this will be familiar. If not, you need to do a 101 course on Android Development and this stuff will be clear to you.

serverapp module – build.gradle

Let us now, step inside of the serverapp module. There you will find the module specific build.gradle that is shown below. Remember, this one is an App Engine application, so it will utilize the App Engine plugin. We had seen a similar looking build.gradle file in Part 5 of the series.

The serverapp/build.gradle file is shown below:

// Currently, the appengine gradle plugin's appengine devappserver launch doesn't interact well with Intellij/AndroidStudio's
// Gradle integration. As a temporary solution, please launch from the command line.
// ./gradlew modulename:appengineRun
// If you would like more information on the gradle-appengine-plugin please refer to the github page
// https://github.com/GoogleCloudPlatform/gradle-appengine-plugin

buildscript {
 repositories {
 mavenCentral()
 }
 dependencies {
 classpath 'com.google.appengine:gradle-appengine-plugin:1.9.6'
 }
}

repositories {
 mavenCentral();
}

apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'appengine'

sourceCompatibility = 1.7
targetCompatibility = 1.7

dependencies {
 appengineSdk 'com.google.appengine:appengine-java-sdk:1.9.6'
 compile 'javax.servlet:servlet-api:2.5'
}

appengine {
 downloadSdk = true
 appcfg {
 oauth2 = true
 }
}

Some of the important points are:

  • The appengine plugin is required by the buildscript, so we are including it in the buildscript closure. This is same from Part 5.
  • We are applying the plugins : java, war and appengine. This is standard stuff again since we have java files, war tasks are needed to build/assemble the package into a WAR file and appengine plugins adds several tasks that include running local dev server, uploading your application to appengine runtime in the cloud, etc.
  • Take a look at dependencies closure that we have seen earlier. It includes the App Engine SDK 1.9.6 and also the Servlet jar , since this is a basic JAva Web app and we require the JAR to compile our Servlet classes. Take a peek into src/main/java folder and you will get it why.
  • And finally we have the appengine closure. We looked at that too in Part 5. The downloadSDK downloads the App Engine SDK in case you do not have it locally in the cache. Additionally, we are using the OAuth 2 mechanism in case you wish to deploy your project via the appengineUpdate task. This will open up a browser window, where you authenticate, get a code and paste it back to proceed with update of your application in to the cloud.

That’s about it really as far as the Gradle stuff is concerned. Once you understand the multi-module projects in Gradle, it becomes that much simple to understand the files that are getting generated in Android Studio vis-a-vis Gradle.

Gradle Tasks

Since we have now two modules in the application and each of them utilizes the respective plugins for Android and App Engine, you will notice that the Gradle tab found in the vertical navigation bar on the right will have tasks categorized based on both the modules.

ep7-3

Since we added the serverapp module, you can see that various App Engine tasks are now available. The Gradle support inside of Android Studio has done a gradle tasks in the background for both the folders/modules and presented the tasks here for you.

ep7-5

To execute any of the tasks, without the hassle of going to the terminal and execute it, simply double click on the tasks and it will start executing.

Keep in mind that anytime you make any changes to your build files, do remember to click on the Sync Project with Gradle Files as shown below. It should launch the build and you should be able to see the Gradle commands getting executed in the Gradle Console.

gradle-ep6-11

App Engine – Start / Stop Application

If you develop App Engine applications, then you will end up starting / stopping the local server. We had seen this in Part 5 via the App Engine plugin for gradle. Over here we can do that right within the terminal itself. Remember that as mentioned in the previous section, you can always double click on one of the Gradle Tasks and it should launch up. But the Terminal gives you good control over things and it sort of reinforces our understanding from previous episodes and hence I am covering that here. 

To start the Terminal, simply click on the Terminal Option that you will see in the status bar at the bottom. It will launch up a Terminal window for you and the directory will be shown.

ep7-7

When it opens up, it does so within the app module. I just go back one level to the root folder where the gradle wrapper files (gradlew and gradle) are present.

Remember that the task appengineRun was used to launch the App Engine dev server locally. We are simply firing up that task over here. Since it is inside the serverapp module, we are providing the whole namespace here. i.e. modulename:taskname

This will launch the App Server as shown below:

ep7-8

Once the Local Dev Server is started, we can test out if it is running by navigating to the localhost:8080 URL as shown below. And all should work well.

ep7-9

ep7-10

 

You can always open up another Terminal window by clicking on the sign. Over here, we open another terminal and actually fire the appengineStop task to shutdown the Dev Server when we want.

ep7-11

Recommended: Do try out other appengine Tasks directly from the Terminal and or by clicking on the tasks in the Gradle View.

Moving forward

This tutorial helped you understand a multi-module Android project within Android Studio. We took our existing knowledge of Gradle for multi-module Java projects and applied it to understand the files that were generated for both the Android and App Engine module within a particular Android Studio project.

In the next episode, we shall continue keep exploring the multi-module project inside of App Engine. Specifically, we shall look at another App Engine module Endpoints that helps you create a backend for your Android applications.

Till then, Happy Gradling!

Posted in Tools | 5 Comments

Gradle Tutorial : Part 6 : Android Studio + Gradle

Welcome to Part 6 of the Gradle Tutorial. In the previous episode i.e. Part 5, we took a look at building / running / deploying App Engine Java Web Applications via Gradle.

In this part of the tutorial, we shall take our first look at Android Studio and understand the Gradle environment in Android Studio. Since you are now aware of the basics of single, multiple Java projects with Gradle, it should become a bit easier to understand what they generate for you.

Along the way, we shall also take a look at various tabs, configuration settings and the terminal inside of Android Studio, so that you can opt to run gradle via the command line/terminal even inside of Android Studio. This will help you use the knowledge that you have gained so far.

Our goal in this episode will only be to familiarize ourselves with the Gradle environment inside Android Studio. It is by no means expected to be an Android tutorial.

as_plus_gradle

This part assumes that you have installed Android Studio on your development machine and that you are familiar with basic Gradle commands, project structure and files as we have seen in the series so far.

I have used Android Studio (Beta) 0.8.6 on Windows for this blog post. It is not necessary to have the same version or the OS, things should be pretty much similar from a Gradle perspective.

The points that we shall cover in this blog post are as follows:

  • Project Template Gradle Configuration Settings in Android Studio
  • Generate a basic Android Application and understand Project specific settings for Gradle
  • Understand Gradle Project build files generated for a basic Android Application
  • Look at various windows Tabs available for working with Gradle. For e.g. Gradle, Gradle Console and Terminal window tabs.
  • Look at how we can add more dependencies to our Android Project

Project Template Gradle Settings

Go ahead and launch Android Studio. Close all the Projects in case a default one opens up. This should bring you to the Quick Start window that you see below. The Configure option that you see below is an important one and helps you configure almost anything in the Android Studio IDE. And that includes some global Gradle settings.

Click on Configure. 

gradle-ep6-1

This will bring you to the Configure options as shown below. Some of these will be recognizable now. For e..g the SDK Manager, that allows you to download the required Android SDK libraries. Click on Settings as shown below:

gradle-ep6-2

 

This will bring up the Settings window and you will see a Gradle option as highlighted below. Do not worry about the Linked Gradle Projects, which is empty, once we create a project things will get linked but for now, ignore it.

gradle-ep6-3

 

Over here you see some global settings as follows:

  • Offline work : If you check this option, Gradle will use things from the cache itself for dependency resolution. In case the files are not there in the cache, then it will result in a build error.
  • The Service Directory Path is the default Gradle Home directory. This is where the cache is maintained, etc.
  • Gradle VM Options can be used to tweak some JVM Settings and/or provide some property files.

Do not worry too much about this but be aware of the Offline setting. This can cause some heartburn in case you have checked it i.e. enabled offline and then after adding some dependency, Gradle is not able to resolve it since it is going to look into the cache itself.

Android Application

Allright, lets go ahead and generate our Android Application. We are going to be using the Android Studio Wizard to do that. Nothing fancy.

Click on New Project in the Quick Launch dialog. This should bring up the New Project wizard as shown below. I have stuck to tradition and called my project HelloWorldAndroid :-)

gradle-ep6-4

Just take all the defaults as shown in the next screens for the wizard.

gradle-ep6-5

gradle-ep6-6

gradle-ep6-7

Click on Finish to end the wizard and then it weaves some magic to generate the Android Studio project files for you. Be a bit patient.

Gradle Project Files

The Project is now created and is opened up in Android Studio. Go to File -> Settings and this should bring up the Project settings dialog as shown below:

gradle-ep6-8

This looks similar to the Project Template dialog that we saw earlier. Except that the Project (HelloWorldAndroid) has got linked and there are additional Project-level settings that have got added. I suggest that you stick to the default ones. For e.g. there is a default Gradle distribution that is already shipped and linked up in your project, so that you do not need to separately go ahead and download Gradle and set it up. Choose this in most scenarios.

However, if you wish to be very specific and have requirements that require you to use your own Gradle build, then do provide the local gradle distribution. Click on the Gradle home selector option and point it to the root of your Gradle distribution.

For most of us, the default Gradle Wrapper is recommended and it will suit our needs.

Now, take a look at the Project Files that have got generated. You should have a similar screenshot that I have put below. I have highlighted the Gradle specific files for you to take a look at:

gradle-ep6-9

 

Let us go over these now. The files circled in green are the default gradle wrapper files that you can use from the terminal / command window (we shall see that in a while). They are nothing but a way for the IDE and yourself to launch gradle on your own anytime. We will look at it a little later in this post, but keep in mind that they are the files to run gradle.

In Part 3, we had covered multiple Java projects and how at the root folder, we can specify the settings.gradle and build.gradle files that apply across all the modules. Android Studio follows the same convention. 

In short, what we have is an Android Project and a module (app) inside of it. That module is an Android application that will need to be built as per Android rules and would need the Android Gradle plugin. Simple enough , isn’t it ?

So, let us look at the settings.gradle file at the root:

include ':app'

It includes just the app module, which is how we had seen in Part 3 of this series.

Take a look at the build.gradle file at the root:

// Top-level build file where you can add configuration options 
// common to all sub-projects/modules.

buildscript {
 repositories {
   jcenter()
 }

dependencies {
 classpath 'com.android.tools.build:gradle:0.12.2'

// NOTE: Do not place your application dependencies here; they 
// belong in the individual module build.gradle files
 }
}

allprojects {
  repositories {
    jcenter()
  }
}

This should be understandable too. For allprojects, we are specifying the repository to be used. JCenter is another repository similar to MavenCentral that we had seen earlier. Additionally, we had seen in the earlier episode, how buildscript can be used to specify what is going to be needed to run the script itself. At that time, we had included the App Engine Plugin/SDK and now we have the Gradle library for the Android Tools Project.

Let us now, step inside of the app module. There you will find the module specific build.gradle that is shown below. Remember it is an Android app, so it will utilize the Android plugin and have Android plugin specific closures that make sense when compiling, building , running, packaging the Android application.

The app/build.gradle file is shown below:

apply plugin: 'com.android.application'

android {
  compileSdkVersion 20
  buildToolsVersion "20.0.0"

  defaultConfig {
     applicationId "com.mindstorm.helloworldandroid"
     minSdkVersion 19
     targetSdkVersion 20
     versionCode 1
     versionName "1.0"
  }

  buildTypes {
    release {
      runProguard false
      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
      }
    }
 }

dependencies {
 compile fileTree(dir: 'libs', include: ['*.jar'])
}

Some of the important points are:

  • We specify the use of the Android plugin via the apply plugin command
  • Take a look at dependencies closure that we have seen earlier. Currently it simply adds all the JAR Files that you might add to the libs folder. Alternately, you can also add more of your dependencies here as we have seen earlier.
  • The android closure is a standard one that is used for specifying which SDK version to use for compiling, the minimum SDK Version supported, package name, versioning information and pro Guard related stuff. If you have built Android applications, this will be familiar. If not, you need to do a 101 course on Android Development and this stuff will be clear to you.

That’s about it really as far as the Gradle stuff is concerned. You can see easily that it you have dependencies on other JARs, simply drop them into your libs folder. Alternately, you can add to the dependencies closure by specific repository entries for your dependent files.

Gradle Tasks

On the extreme right side of Android Studio, you will find a vertical navigation bar, which has tabs like Maven Projects, Gradle and Commander.

Go ahead and click on the Gradle tab in that navigation bar. You will be presented with the Project -> Module -> All the Gradle tasks that come under this project. Just like how you do a gradle tasks to determine what are the tasks available for the project, this window basically has done that for you and shows you the tasks available.

gradle-ep6-10

 

 

You do need to refer to the documentation for the respective plugin since it will have information on all the tasks and what they can do.

To execute any of the tasks, without the hassle of going to the terminal and execute it, simply double click on the tasks and it will start executing. And the output is what will be visible in the Gradle console, that we shall see next.

Gradle Console

The Gradle console is tucked away in at the right bottom corner. Simply click on it, to bring it up and you shall see a output from Gradle tasks/commands as they are being executed. As a test, you can launch any of the Gradle tasks that we saw earlier via the Gradle Tasks window. Or simply go to the main menu and click on Rebuild Project, Make Project or something like that and it will show you the output from running Gradle.

gradle-ep6-12

This is very handy when you have an error since it is important for you to see what went wrong during the build.

Use the Terminal

Welcome to the Terminal. In the previous episodes, we were running all Gradle stuff directly from the command line or the terminal. The Android Studio developers have made it easier by integrating it within Android Studio itself, so that you do not need to go out.

This is useful , especially if you are perfectly clear on the tasks that you want to launch and prefer launching it yourself rather than some obscure option somewhere on the menu.

gradle-ep6-13

 

To start the Terminal, simply click on the Terminal Option that you will see in the status bar at the bottom. It will launch up a Terminal window for you and the directory will be shown. You can now execute any Gradle tasks. For e.g. since we have mentioned that Gradle wrapper is provided to you by default, notice how I execute the Gradle tool from the command line to display all the tasks. Go ahead and try out a few commands.

See the + sign in the Terminal Window. You can use that to launch multiple terminals and fire different commands from there if you prefer that sort of a developer workflow. For e.g. in a subsequent episode, we shall see how we can use App Engine modules within Android Studio projects and then use two instances of Terminal : one for launching the Development Server and the other for Shutting down the Development Server and so on.

Tip

Typically if you update any of the Gradle files, it is recommended that you click on the Sync Project with Gradle Files option. This will fire off the default task that has been configured for your project. Just make this option your friend.

gradle-ep6-11

Adding Project Dependencies

Finally, a few words on adding additional dependencies in your project. At a high level, there are 2 ways that you can do that:

  1. You can directly modify the build.gradle files and the dependencies closure. Nothing stops you from doing that. These are straight forward files, go ahead and modify them and save them. Once you save your files, do remember the tip above of clicking the Sync Project with Gradle Files.
  2. If you prefer to use the help of a User Interface to fill out the dependencies (either on JARs, Maven Repository JARs or even other modules in the project), you can choose do the following : Right Click on the module (app) and then choose Module Settings as shown below:gradle-ep6-14
  3. This will bring up the Dialog as shown below:gradle-ep6-15
    You can notice that you can modify values on any of the Tabs and this will reflect in the build.gradle file accordingly.
  4. Let us specifically look at dependencies. Click on the Dependencies tab. This will show the current values that we have the dependencies closure for the build.gradle file in the app module.gradle-ep6-16
  5. Now, let us look at how to add more dependencies inside of this closure. Simply click on the button. The following options come up:gradle-ep6-17a) Library Dependency b) File Dependency and c) Module Dependency. And these are pretty much the different ways of adding dependencies that we have seen in Part 2 and Part 3.
  6. Let us click on Library Dependency. This will bring up the following dialog where we can specify some entry from the central Maven Library or even pick one that we may have locally in our cache. For e.g. Joda Time.gradle-ep6-18
  7. If we click OK, you will find that the dependencies closure of our build.gradle file will be modified accordingly as shown below:
    dependencies {
    
      compile fileTree(dir: 'libs', include: ['*.jar'])
      compile 'joda-time:joda-time:2.3'
    
    }

    Go ahead and try adding more dependencies either from Maven Repository or even from local files, etc. Remember to always ave and Sync Project with Gradle Files to kick off the build.

Moving forward

This tutorial helped you understand how Gradle is seamlessly tied into Android Studio and basic understanding of Gradle files, configurations and various tabs.

In the next episode, we shall continue to stay inside of Android Studio. and look at App Engine modules inside of your Android Studio Project.

suggest to read up on the Gradle Plugin User Guide for Android Tools. Since this is the tool that Google wants us to use moving forward for Android Development, it is important to make this user guide your friend.

Till then, Happy Gradling!

References

Posted in Tools | 3 Comments

Gradle Tutorial : Part 5 : Gradle App Engine Plugin

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.

gradle

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::

helloappenginegradle
|- src
   |- main
      |- java
         |- hellogradle (Sources inside this package)
         |- META-INF
             |- jdoconfig.xml
             |- persistence.xml
         |- log4j.properties
      |- webapp
         |- WEB-INF
            |- appengine-web.xml
            |- logging.properties
            |- web.xml
         |- favicon.ico
         |- index.html
|- build.gradle

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:

  1. 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.
  2. 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. 
  3. The java folder contains the Java sources and other resource files. We have the standard Hello Gradle Servlet present in the sources.
  4. 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.
  5. 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.

build.gradle

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.

apply plugin: 'war'
apply plugin: 'appengine'

def appId = "hellogradle" 
def appEmail = "romin.irani@mindstormsoftware.com"
def appengineVersion = "1.9.6"

buildscript { 
  repositories { 
     mavenCentral()
  } 
  
  dependencies {
    classpath "com.google.appengine:gradle-appengine-plugin:1.9.6
  }
}

repositories {
  mavenCentral()
}

dependencies {
 appengineSdk "com.google.appengine:appengine-java-sdk:${appengineVersion}"
 compile "javax.servlet:servlet-api:2.5"
 compile "com.google.appengine:appengine-api-1.0-sdk:${appengineVersion}"
}

appengine {
  httpPort = 8888
  downloadSdk = true

  appcfg {
    email = "${appEmail}"
    noCookies = true
    oauth2 = true
  }
}

Let us go through the file in brief:

  1. We are applying the WAR plugin. This by default also applies the java plugin as we have seen in earlier episodes.
  2. We then apply the AppEngine plugin.
  3. 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.
  4. 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.
  5. 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.
  6. 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. 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:

gradle tasks

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.

Google App Engine tasks
-----------------------
appengineConfigureBackends - Configures backends on App Engine.
appengineCronInfo - Get cron information from App Engine.
appengineDeleteBackend - Deletes backend on App Engine.
appengineDownloadApp - Retrieves the most current version of your application.
appengineDownloadSdk - Downloads and sets Google App Engine SDK.
appengineEndpointsExpandClientLibs - Expand the generated client libraries sourc
es in to build/generated-source
appengineEndpointsExportClientLibs - Export the generated client libraries jars
to a user-defined destination
appengineEndpointsGetClientLibs - Generate Endpoints java client libraries for c
lasses defined in web.xml
appengineEndpointsGetDiscoveryDocs - Generate Endpoints discovery docs for class
es defined in web.xml
appengineEndpointsInstallClientLibs - Install generated client libs into the loc
al Maven repository
appengineEnhance - Enhances DataNucleus classes.
appengineExplodeApp - Explodes WAR archive into directory.
appengineFunctionalTest - Runs functional tests
appengineListBackends - Lists backends on App Engine.
appengineLogs - Download logs from App Engine.
appengineRollback - Undoes a partially completed update for the given applicatio
n.
appengineRollbackBackend - Rolls back backend on App Engine.
appengineRun - Starts up a local App Engine development server.
appengineStartBackend - Starts backend on App Engine.
appengineStop - Stops local App Engine development server.
appengineStopBackend - Stops backend on App Engine.
appengineUpdate - Updates your application on App Engine.
appengineUpdateAll - Updates your application and all backends on App Engine.
appengineUpdateAllBackends - Updates all backends on App Engine.
appengineUpdateBackend - Updates backend on App Engine.
appengineUpdateCron - Updates scheduled tasks definition (known as cron jobs) on
 App Engine.
appengineUpdateDos - Updates DoS protection configuration on App Engine.
appengineUpdateIndexes - Updates indexes on App Engine.
appengineUpdateQueues - Updates task queues on App Engine.
appengineVacuumIndexes - Deletes unused indexes on App Engine.
appengineVersion - Prints detailed version information about the SDK, Java and t
he operating system.

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:

gradle appengineRun

You should see the following output in the console:

E:\helloappenginegradle>gradle appengineRun
:appengineDownloadSdk
:compileJava 
:processResources UP-TO-DATE
:classes 
:war 
:appengineExplodeApp 
:appengineRun

..... <Several other console statements>

Aug 15, 2014 3:18:38 AM com.google.appengine.tools.development.AbstractModule st
artup
INFO: The admin console is running at http://localhost:8888/_ah/admin
Aug 15, 2014 8:48:38 AM com.google.appengine.tools.development.DevAppServerImpl
doStart
INFO: Dev App Server is now running
> Building 85% > :appengineRun

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:

  appengine {
     httpPort = 8888
     .....
  }

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:

gradle appengineUpdate

But before you go right ahead and launch it, let us recollect first what is needed to deploy the application to App Engine.

  1. You need to have the Application Id and version of the App Engine application that you want to deploy in the cloud. These values will need to be set in the WEB-INF\appengine-web.xml file as is the standard for Java App Engine applications.
  2. You need to have your Account Name and Password ready, so that you can be authenticated/authorized to move forward with deployment.
  3. 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)

...
def appId = "hellogradle"
def appEmail = "romin.irani@mindstormsoftware.com"
....
appengine {
  httpPort = 8888
  downloadSdk = true

  appcfg {
    email = "${appEmail}"
    noCookies = true
    
  }
}

 

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.

To deploy the project, we will fire the following command:

gradle appengineUpdate

This will go through the necessary steps and you will find that it waits at the password prompt as shown below:

E:\helloappenginegradle>gradle appengineUpdate
:appengineDownloadSdk
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:war UP-TO-DATE
:appengineExplodeApp UP-TO-DATE
:appengineUpdate
Reading application configuration data...
Aug 15, 2014 10:46:20 AM com.google.apphosting.utils.config.AppEngineWebXmlReade
r readAppEngineWebXml
INFO: Successfully processed E:/helloappenginegradle/build/exploded-app\WEB-INF/
appengine-web.xml
Aug 15, 2014 10:46:20 AM com.google.apphosting.utils.config.AbstractConfigXmlRea
der readConfigXml
INFO: Successfully processed E:/helloappenginegradle/build/exploded-app\WEB-INF/
web.xml

Beginning interaction for module default...
> Building 85% > :appengineUpdatePassword for romin.irani@mindstormsoftware.com:

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:

0% Created staging directory at: 'C:\Users\irani_r\AppData\Local\Temp\appcfg8064
659880720537353.tmp'
5% Scanning for jsp files.
20% Scanning files on local disk.
25% Initiating update.
28% Cloning 3 static files.
31% Cloning 25 application files.
40% Uploading 0 files.
52% Initializing precompilation...
90% Deploying new version.
95% Closing update: new version is ready to start serving.
98% Uploading index definitions.

Update for module default completed successfully.
Success.
Cleaning up temporary files for module default...
BUILD SUCCESSFUL
Total time: 37.594 secs

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:

appcfg {
 
 email = "${appEmail}"
 noCookies = true
 oauth2 = true

}

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:

E:\helloappenginegradle>gradle appengineUpdate
:appengineDownloadSdk
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:war UP-TO-DATE
:appengineExplodeApp UP-TO-DATE
> Building 85% > :appengineUpdate

Next, it will popup a browser window, where you will authorize the process of deployment via your account. A screenshot is given below:

gradle-ep5-3 gradle-ep5-2

Once you accept the process, it will show the following:

gradle-ep5-3

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:

> Building 85% > :appengineUpdate4/tUZl_B2_k7AU4xLkbVaqLLmbCQ4c.ssxy9yQGz7kTBrG_
bnfDxpKI8UGwjwI
:appengineUpdate
Please enter code: Reading application configuration data...
Aug 15, 2014 10:56:40 AM com.google.apphosting.utils.config.AppEngineWebXmlReade
r readAppEngineWebXml
INFO: Successfully processed E:/helloappenginegradle/build/exploded-app\WEB-INF/
appengine-web.xml
Aug 15, 2014 10:56:40 AM com.google.apphosting.utils.config.AbstractConfigXmlRea
der readConfigXml
INFO: Successfully processed E:/helloappenginegradle/build/exploded-app\WEB-INF/
web.xml
Beginning interaction for module default...
0% Created staging directory at: 'C:\Users\irani_r\AppData\Local\Temp\appcfg8235
825904506985013.tmp'
5% Scanning for jsp files.
20% Scanning files on local disk.
25% Initiating update.
28% Cloning 3 static files.
31% Cloning 25 application files.
40% Uploading 0 files.
52% Initializing precompilation...
90% Deploying new version.
95% Closing update: new version is ready to start serving.
98% Uploading index definitions.
Update for module default completed successfully.
Success.
Cleaning up temporary files for module default...
BUILD SUCCESSFUL

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:
        // Persistence
        compile 'org.ow2.asm:asm:4.0'
        compile 'org.datanucleus:datanucleus-api-jpa:3.1.3'
        compile 'org.datanucleus:datanucleus-api-jdo:3.1.3'
        compile 'com.google.appengine.orm:datanucleus-appengine:2.1.2'
        compile 'org.datanucleus:datanucleus-core:3.1.3'
        compile 'org.apache.geronimo.specs:geronimo-jpa_2.0_spec:1.0'
        compile 'javax.jdo:jdo-api:3.0.1'
        compile 'javax.transaction:jta:1.1'
  • 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)

for e.g.

enhancer {
version
= "v2"
enhanceOnBuild
= true
}

Moving forward

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 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!

References

Posted in Tools | 8 Comments

Gradle Tutorial : Part 4 : Java Web Applications

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

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. Jetty 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.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 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 Jetty 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 classes 'main'.
clean - Deletes the build directory.
jar - Assembles a jar archive containing the main classes.
testClasses - Assembles classes 'test'.
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:

E:\mywebapp\web>gradle assemble
:utils:compileJava
:utils:processResources UP-TO-DATE
:utils:classes
:utils:jar
:web:compileJava
:web:processResources UP-TO-DATE
:web:classes
:web:war
:web:assemble

BUILD SUCCESSFUL

Total time: 5.804 secs

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 Jetty 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 Jetty plugin can do for you.

To do this, we will modify our build.gradle file for the web folder as shown below:

apply plugin: "war"
apply plugin: "jetty"

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

httpPort = 8080

Notice the additional entries that we have added in bold. We have simply applied the Jetty plugin and also provided one of the standard properties 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 Jetty have also got added now (only the additional Jetty tasks are shown in the output below):

Web application tasks
---------------------
jettyRun - Uses your files as and where they are and deploys them to Jetty.
jettyRunWar - Assembles the webapp into a war and deploys it to Jetty.
jettyStop - Stops Jetty.

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

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

gradle jettyRunWar

This will build things, if they are updated and you should see output similar to the following:

E:\mywebapp\web>gradle jettyRunWar
:utils:compileJava UP-TO-DATE
:utils:processResources UP-TO-DATE
:utils:classes UP-TO-DATE
:utils:jar UP-TO-DATE
:web:compileJava UP-TO-DATE
:web:processResources UP-TO-DATE
:web:classes UP-TO-DATE
:web:war UP-TO-DATE
> Building 88% > :web:jettyRunWar > Running at http://localhost:8080/web

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:

gradle-ep4-2

You can even visit the servlet configured if you want:

gradle-ep4-3

To stop the Jetty Web Server, you can open up another console/terminal and fire the following command:

gradle jettyStop

Moving forward

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

I recommend that you also look at a couple of examples that ship with the standard Gradle build. These examples are present in samples/webApplication folder of your Gradle installation directory. The folder has two examples : quickstart, which is sort of what we have seen here. The other example customized is interesting and shows how you can move away from convention and specify exactly what files and from where it should take to build the Web application.

In the next episode, we shall look at the Google App Engine plugin in Gradle, and how it can help build/run/deploy our Java Web applications written for the App Engine platform.

Till then, Happy Gradling!

References

Posted in Tools | 6 Comments