Google App Engine (GAE) Java API Part 2: Setup and Introduction

Share this article

In the first part of this series, we went through the basic environment GAE offers the developer. You must be excited to get yourself into coding your first application and seeing it live! Setting up the IDE for GAE development is a fairly simple task: simply install the GAE plugin in Eclipse version of your choice and you are good to start development on GAE.

But before we actually get into APIs and services GAE can offer, let’s understand the application structure and configuration which affects how your application will work in runtime. This will also take us through some interesting aspects of the environment, and lead to better design and planning of the application.

Deployment Descriptor: web.xml

The deployment descriptor of a web app on GAE as very much like any other web application, you configure Servlet and JSP URL mappings in the same fashion or URLs are secured and roles specified the same way as in a web application. Filters and error handlers can also be leveraged in the same fashion. A few minor differences to note: EJB/JNDI and the like aren’t supported, obvious since we don’t have an EJB container. The load-on-start-up does not load the servlet at application start-up but when web server receives the first request. Some of the usual configurations like configuring a ServletContextListener or load-on-startup parameters can be configured, but are placed in appengine-web.xml.

App Config: appengine-web.xml

appengine-web.xml  file is a mandatory requirement for a GAE web app, and at bare minimum it houses the application id and version. While deploying the application, the version number is used to decide whether to deploy to existing version if a match is found, or to deploy to a new version if no match is found. This is particularly helpful to have multiple instances of the application for testing while not touching the live instance. Though note that the datastore is shared across versions of an application.

<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
 <application>my-app</application>
 <version>2</version>
</appengine-web-app>

In the above XML, the my-app application’s version 2 is being deployed.

Serving Static Content

Static content can be marked by <static-files> tag so that all static content is served by a separate web server which is a good practice in web applications as you might be aware. The static content does not change much in lifecycle of an application and serving by the static server leaves the container/app server to focus on dynamic content, which it is best at. This includes the expression first taken into account, and even if you don’t specify a default once are applied, followed by application of exclude expression.

The following example marks all jpg files as static except for those in the classes directory. A similar expression can be defined for resource files with the </resource-files> tag. The expiration parameter inside the include tag sets the expiration of cache for browsers, for example in the below example set to 36 hours.

<static-files>
       <include path="/**.jpg" expiration="1d 12h />
       <exclude path="/classes/**.jpg" />
</static-files>

System and Environment Properties

System and environment level properties can be set using the following tags:

    <system-properties>
           <property name="my-app.user.timeout" value="300" />
    </system-properties>
    <env-variables>
       <env-var name="ENV_VAR_NAME" value="ENV_VAR_VALUE" />
    </env-variables>

Configuring Inbound Services

There are certain inbound services like mail or XMPP which are by default disabled. If you need to enable them, you need to add them specifically to appengine-web.xml like in the example below.

<inbound-services>
       <service>channel_presence</service>
</inbound-services>

Services

Description

mail

Enables incoming emails

channel_presence

Enables clients to use channel and enables notification

warmup

Used to warmup of certain application components at startup

xmpp_presence

xmpp_message

xmpp_subscribe

XMPP related services

Session Mechanism

GAE offers a session mechanism using the servlet session interface, but is disabled by default and to enable it you need to add the following to appengine-web.xml:

<sessions-enabled>true</sessions-enabled>

The data of a session is stored in datastore with entities of type _ah_SESSION and is also stored in MEMCACHE for faster access. You can reduce the latency by marking the session data written to datastore to be asynchronous. The session data writing to datastore is done by a queue, if unspecified is “default” queue, but can be configured to other names.

<async-session-persistence enabled="true" queue-name="sessionQueue"/>

Index Config

Indexes are used to speed up retrieval of data. In GAE the indexes can be defined by the developer/user and are also auto generated by the development server.

File name

Details

WEB-INF/datastore-indexes.xml

Indexes defined by user/developer

WEB-INF/appengine-generated/datastore-indexes-auto.xml

Indexes auto generated by development server when queries are made to data

Let’s look at structure of a typical datastore-indexes.xml and two key aspects it controls.

<?xml version="1.0" encoding="utf-8"?>
<datastore-indexes
 autoGenerate="true">
   <datastore-index kind="Employee" ancestor="false">
       <property name="employeeNumber" direction="asc" />
   </datastore-index>
</datastore-indexes>

First look at the child element, <datastore-index>. This tag defines the Entity kind for which you will define index. The ancestor attribute shall be true if the index supports filtering of entity by parent entity group.  Property tag defines name of the property wich is indexes and direction which can be “asc” or “dsc”.

The second aspect which is defined in the parent tag of the file i.e. inside <datastore-indexes> controls how the auto-generated indexes are handled.

autoGenerate=”true”

– By default true If user defined index file does not exist.

– Updated when a development server hits a query for which no index is defined in either index file, and adds index to datastore-indexes-auto.xml

– When you upload application to GAE, both index files are used to build indexes on GAE

autoGenerate=”false”

– Indexes in datastore-indexes-auto.xml are ignored

– When application hits a query for which there is no index defined in datastore-indexes.xml an exception is raised

Scheduled Tasks: cron.xml

Define and schedule crons

Cron is a very familiar word for UNIX-like OS users and a powerful tool to get some tasks done at intervals, periodically or just one-off cases, but fires on its own by system at the time/interval specified. GAE crons are simple to use and plug very well in your web app. The job is defined in a servlet, and you configure URL for it in deployment descriptor. URL for job and schedule are only two mandatory requirements to configure the cron in cron.xml. If you don’t define target, it will use the default app instance, but you can choose to fire the cron against a specific version of instance to run against. Cron file can have upto 20 crons and the XML file resides in WEB-INF directory of your application.

Schedule format is almost English like “every 6 hours” or “1st Tuesday of jan,apr,jun,oct 05:00”

<?xml version="1.0" encoding="UTF-8"?>
<cronentries>
 <cron>
   <url>/DailyReport</url>
   <description>Optional Desc goes here</description>
   <schedule>every day 11:30</schedule>
   <timezone>America/New_York</timezone>
   <target>version-2</target>
 </cron>
</cronentries>

Access and Secure Cron Jobs

As long as the entry in “url” of cron is accessible as a URL of web application, the cron job should run fine. The next thing you need to take care of is not to allow access to the cron by any user other than the system/admin, by adding the URL and corresponding admin roles who can access it in the deployment descriptor.

We have understood pretty much all of GAE configurations and environment so far. We didn’t cover backend and task queue configurations as they would be more appropriately explained in context of those special topics. We are ready to dive now, after ground and sky demo! So keep a watch on on next part and setup your IDE and brains for some hands on!

Vishal BiyaniVishal Biyani
View Author

My name is Vishal Biyani! I am an avid developer and a cloud enthusiast! I am lucky enough to witness some very exciting changes in technology and data landscape.

Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week