The Book: GAE and GWT App Development

Google App Engine Java and GWT Application Development

This book is designed to give developers all the information they need to develop their own GAE+GWT applications, with a particular focus on some of the technologies useful for building scalable social-media-oriented applications. It is an easy-to-follow guide that shows you how to get the most out of combining the powerful features of GAE and GWT. It provides you with solutions to many of the problems that arise in developing, maintaining, and scaling web applications.


Over the course of the book, you are guided by the development of a sample application using the Google Web Toolkit (GWT) and App Engine. To make things easier for you, all application building blocks are explained in detail, walking you through the development process step by step.

The book comes with the full source code of Connectr, a social RSS aggregator.

This book addresses all the topics needed to build a cloud-based enterprise grade web app including Google Web Toolkit interface building, UIBinder, CSS resource, client bundle, Remote Procedure Calls (RPC) with error handling and automatic retries, JDO, transaction, memcache, event bus, traditional MVP, MVP activities and places, server push with Channel API, Cron, task queues, XMPP, session management, authentication with Google, Twitter and Facebook and much more.

What this book covers

Chapter 1, Introduction, introduces the approaches and technology covered in the book, and discusses what lies ahead.

Chapter 2, Using Eclipse and the Google Plugin, describes the basics of setting up a project using the Eclipse IDE and Google's GWT/GAE plugin. Topics include defining, compiling and running an Eclipse GWT/GAE project, and using the GWT developer browser plugin with the interactive debugger. The chapter also covers how to set up an App Engine account and create applications, and how to deploy an app to App Engine and access its Admin Console.

Chapter 3, Building The Connectr User Interface with GWT, focuses on GWT, and building the fi rst iteration of the Connectr application's frontend. The chapter looks at how to specify widgets, with a focus on declarative specification using GWT's UIBinder and using the GWT RPC API for server-side communication.

Chapter 4, Persisting Data: The App Engine Datastore, covers Datastore basics. In the process, the first iteration of Connectr's server-side functionality is built. The chapter looks at how the Datastore works, and the implications of its design for your data models and code development. It covers how to use Java Data Objects (JDO) as an interface to the Datastore and how to persist and retrieve Datastore entities.

Chapter 5, JDO Object Relationships and Queries, builds on the topics of Chapter 4. It describes how to build and manage JDO objects that have relationships to each other, such as one-to-many and one-to-one parent-child relationships. It also covers how to query the Datastore, and the important role that Datastore indexes play in this process.

Chapter 6, Implementing MVP, an Event Bus and Other GWT Patterns, builds on the client-side code of Chapter 3, and shows how to make the frontend code modular and extensible. It accomplishes this via use of the MVP (Model-View-Presenter) and Event Bus design patterns, history/bookmark management, and an RPC abstraction, which supports call retries and progress indicators.

Chapter 7, Background Processing and Feed Management, centers on defining and running decoupled backend asynchronous tasks. In the process, the chapter introduces several App Engine services, including URLFetch and Task Queues, shows the use of Query Cursors to distribute Datastore-related processing across multiple Tasks, and introduces the use of Java Servlets and the incorporation of third-party libraries in a deployed application.

Chapter 8, Authentication using Twitter and Facebook OAuth and Google Accounts, adds authentication, login, and account functionality to Connectr, allowing it to support multiple users. The chapter demonstrates the use of both the Google Accounts API and the OAuth protocol for creating user accounts.

Chapter 9, Robustness and Scalability: Transactions, Memcache, and Datastore Design, delves into more advanced Datastore-related topics. The chapter investigates Datastore- related means of increasing the robustness, speed, and scalability of an App Engine app, including several ways to design data classes for scalability and to support efficient join-like queries. The chapter also introduces App Engine transactions and Transactional Tasks and the use of Memcache, App Engine's volatile-memory key-value store.

Chapter 10, Pushing fresh content to clients with the Channel API, covers the implementation of a message push system using the App Engine Channel API, used by Connectr to keep application data streams current. The chapter describes how to open back-end channels connected to client-side socket listeners, and presents a strategy for preventing the server from pushing messages to unattended web clients.

Chapter 11, Managing and Backing Up Your App Engine Application, focuses on useful App Engine deployment strategies, and admin and tuning tools. It includes ways to quickly upload configuration fi les without redeploying your entire application and describes how to do bulk uploads and downloads of application data. The chapter also discusses tools to analyze and tune your application's behavior, and the App Engine billing model.

Chapter 12, Asynchronous Processing with Cron, Task Queue, and XMPP, finishes building the server-side part of the Connectr app. The chapter introduces the use of App Engine Cron jobs, configuration of customized Task Queues, and App Engine's XMPP service and API, which supports push notifications. The chapter shows the benefits of proactive and asynchronous updating—the behind-the scenes work that keeps Connectr's data stream fresh—and looks at how App Engine apps can both send and receive XMPP messages.

Chapter 13, Conclusion, summarizes some of the approaches and technology covered in the book, and discusses what might lie ahead.

Detailed Table of Contents
  • Chapter 1: Introduction

    • Overview of the chapter
    • Introduction to Google App Engine
    • The Datastore
    • Introduction to GWT
    • Example application: Connectr
  • Chapter 2: Using Eclipse and the Google Plugin

    • Installing the plugin and supporting software
      • Installing the Java SDK
      • Installing Java on Mac OS X
      • Installing Java on other platforms
    • Installing Eclipse
    • Installing the Google plugin
      • Updating the Google plugin
    • Developing your application in Eclipse
      • Creating a new web application project in Eclipse
        • First look: The anatomy of a web application project
        • The Google plugin wizards and helpers
    • Running and debugging your application
      • Running your application in Development Mode
        • Developing the application in debug mode
        • Development Mode and the GWT browser plugin
        • Defining a run or debug configuration
      • Debugging
      • Compiling your GWT code for production mode
    • Deploying your application
      • Registering and setting an application ID for your application
      • How to set the application ID and version for a project
      • Uploading and deploying your application
      • Your App Engine Admin Console

    • Importing an existing application
      • Adding the Google SDKs to your project's build path
      • Adding third-party JAR files
      • Managing multiple Google SDKs
      • Running Google's demo apps in Eclipse
    • Summary
    • Chapter 3: Building the Connectr User Interface with GWT

      • Installing the (first version of) the Connectr project in Eclipse
      • AJAX and its benefits
      • Why AJAX apps are the way forward
        • AJAX apps minimize traffic and workload both on the client and the server
      • Challenges associated with AJAX programming and how GWT
        solves them
        • JavaScript browser's implementation is not consistent
        • Mastering JavaScript—an uphill battle
        • How GWT comes to the rescue to make developers more efficient
      • Google Web Toolkit overview—modern tools for modern developers
        • GWT user interface building blocks
      • Building the Connectr application—the user interface
        • User interface design elements of Connectr
        • Coding the Connectr user interface
        • Introducing UiBinder to increase productivity
          • Declarative UiBinder versus procedural Java—let's compare
        • Implementing the application layout with UiBinder
        • Tying the view to the Java code
        • Adding custom widgets to UiBinder
        • Adding CSS styles to the application
        • Implementing CSS styles in a global CSS file
        • Adding a logo to the application
        • Catching mouse and keyboard events
      • Grouping CSS files and images for faster speed with ClientBundle
        • Creating a ClientBundle
        • Using image resources in Connectr
        • Automatically checking CSS styles at compile time with CssResource
      • Getting data from the server using GWT RPC
        • Creating the login service
        • Implementing the server-side login service
        • Creating the asynchronous interface
        • Invoking the login service
        • Catching exceptions
      • Summary
      • Chapter 4: Persisting Data: The App Engine Datastore

        • Introduction
          • The Connectr server-side object model
        • The Datastore
          • Datastore entities and their properties
          • Entity keys
          • Datastore queries and indexes
            • Queries are supported by indexes
            • App Engine queries are fast
          • The Datastore versus a relational database
        • JDO
          • Setting up JDO
        • Creating Connectr's data models
          • The PersistenceManager and the PersistenceManagerFactory
          • Making data classes persistable
            • Class and field annotations
          • Persistable field types
            • Core value types
            • Collections and multi-valued properties
            • Datastore keys and JDO key fields
            • Defining keys and core value type fields for Friend and UserAccount
            • Referencing complex objects
            • Serializable objects and serialized fields
            • Embedded classes
          • Data class inheritance
          • Saving, updating, and deleting data objects
            • Persisting an object
            • Fetching a persisted object by its key
            • Deleting a persisted object
            • An object has an associated PersistenceManager
            • Fetch groups
          • Connectr example: creating and modifying UserAccount and
            Friend data objects
            • Creating new Friend objects
            • Deleting a Friend object
            • Fetching a list of Friend objects using the key list
          • Detached objects
          • Detached Data Access Objects and Data Transfer Objects
            • DTOs in the Connectr application
        • Inspecting the Datastore
          • The local development console
          • The App Engine Datastore
            • Browsing the App Engine Datastore
            • Viewing application data statistics
        • Resources
        • Summary
        • Chapter 5: JDO Object Relationships and Queries

          • Modeling relationships between objects
            • Owned relationships and entity groups
            • Uni-directional owned relationships
              • Supporting uni-directional owned relationships in Connectr
              • Dependent children
            • Bi-directional owned relationships
              • Bi-directional one-to-one relationship
              • Bi-directional one-to-many relationship
            • One-to-many Collection ordering
            • Unowned relationships
          • Finding objects—queries and indexes
            • Constructing JDOQL queries
              • Query examples
              • Query filter operators
              • Query filters on fields with multiple values
              • Query sort orders and ranges
            • Executing a query and getting the results
              • Query cursors
              • Unset and unindexed entity fields
            • Deleting by query
            • Batch fetches using a list of keys
            • Keys-only queries
            • Extents: fetching all objects of a particular kind
          • The App Engine Datastore index
            • Automatically-generated indexes
            • Custom indexes
            • Revisiting constraints on queries
              • Exploding indexes
            • Using the Admin Console Datastore index viewer and index vacuuming
            • Side-stepping query constraints
              • Pre-persist callbacks—normalizing Friend name information
          • Summary
          • Chapter 6: Implementing MVP, an Event Bus, and Other GWT Patterns

            • Introducing MVP – The need for design patterns in software
            • Introduction to MVP
              • The view
              • The model
              • The Presenter
            • Connectr MVP application architecture overview
              • Package and file organization
            • Coding MVP into Connectr
              • Starting up the application
              • Inside a presenter
                • Populating the Friend list view
                • Responding to user interface events
              • Listening to the event bus
              • Integrating UiBinder views into MVP
            • Events and the event bus
              • Creating a custom event class
              • Adding an application controller
            • Adding support for browser history
              • Introducing the browser history stack and navigation tokens
            • Implementing browser history management
              • Bootstrapping the browser history at application startup
            • Centralizing RPC calls for better handling and usability and reliability
              • Introducing an encompassing RPC class
              • Displaying a loading indicator when the app is busy
              • Catching server exceptions
              • Retrying a call after failure
              • Putting it all together
            • MVP Development with Activities and Places
              • Building a basic application
              • Traditional MVP versus MVP with Activities and Places
              • Moving parts of ProfileMVP
                • Activities
                • Places and the Place History Mapper
                • Views
              • The Browser Factory
                • Adding deferred binding for iPhone and Android views
              • Activity mapper
              • Putting the pieces together: the onModuleLoad method
            • Summary
            • Chapter 7: Background Processing and Feed Management

              • Overview of the chapter
              • Using Servlets in App Engine
                • Making your Servlets accessible—the deployment descriptor
                • Defining a Servlet
                  • Servlet requests and responses
                  • Generating a response
                • App Engine Servlet limitations
                • Restricting access to a Servlet
                • Sessions
                • The JRE whitelist and system restrictions
                • Accessing static application files
              • Using migrations to evolve the Datastore entities
                • Removing a field from a JDO data class definition
                • Adding a field to a JDO data class definition
                • Facilitating "schema" transitions via migrations
                  • Approach—defining a migration
                  • The Migration interface
                  • Implementing a Migration: The FriendMigration class
                • Running the Migration: A Migration Servlet and the Task Queue
                  • Invoking the Servlet as a web request
                  • Servlet admin authentication
              • Pulling in Feeds: The URL Fetch service
                • App Engine services
                • URL Fetch
                  • Java support for URL Fetch
                • Using java.net.URLConnection
                  • Making an HTTP request
                  • Using HTTP(S) URLConnection objects
                • The "low-level" Java URL Fetch API
                • The ROME and ROME Fetcher RSS/Atom libraries
                  • Downloading the ROME and ROME Fetcher jars and their dependencies
                  • Installing the library JAR files
              • Using RSS/Atom feeds in the Connectr app
                • Adding feed support
                • The feed classes
                  • Adding and removing friend feeds
                • Fetching and updating feeds
                  • Subclassing the ROME Fetcher HttpURLFeedFetcher class
                • Processing changes to Friend URLs
              • Enabling background feed updating and processing
                • Add some test feeds to your app
                • Updating the most recently requested FeedInfo objects
                  • The FeedUpdateServlet mapping
                  • Using an admin-only Servlet URL for the feed update job
                • Updating all feeds for the Friends of a UserAccount
                  • Updating the feeds for a specific Friend
                • A simple Servlet to display feed contents
              • Summary
              • Chapter 8: Authentication using Twitter, Facebook OAuth,
                and Google Accounts

                • Connectr login implementation
                  • Step-by-step implementation of the login sequence
                • OAuth: a new way to login and authorize
                • Integrating with Facebook
                • Registering Connectr with Facebook
                  • Authenticating with Facebook OAuth
                  • Integrating Connectr inside Facebook
                • Authenticating against Google
                • Authenticating against Twitter with OAuth
                  • Registering Connectr with Twitter
                  • Introducing the Twitter login Servlet
                  • Analyzing the Twitter callback Servlet
                • Logging out
                  • Logging out when authenticating against Google or Twitter
                  • Logging out of Facebook
                • Uniquely identifying Connectr users
                • Automatically registering users when they login
                • Summary
                • Chapter 9: Robustness and Scalability:
                  Transactions, Memcache, and Datastore Design

                  • Data modeling and scalability
                    • Reducing latency—read consistency and Datastore access deadlines
                    • Splitting big data models into multiple entities to make access
                      more efficient
                      • Discussion
                    • Splitting a model by creating an "index" and a "data" entity
                    • Use of property lists to support "join" behavior
                      • Supporting the semantics of more complex joins
                  • Using transactions
                    • Transaction commits and rollbacks
                      • Example—a JDO transaction
                      • App Engine transactions use optimistic concurrency
                      • Transaction retries
                    • Transactions and entity groups
                    • Creating entities in the same entity group
                      • Getting the entity parent key from the child key
                      • Entity group design considerations
                    • What you can do inside a transaction
                    • When to use a transaction
                    • Adding transactional control to the Connectr application
                      • Transactional tasks
                  • Using Memcache
                    • Using the App Engine Memcache Java API in Connectr
                      • Memcache error handlers
                      • Memcache statistics
                      • Atomic increment/decrement of Memcache values
                    • Using Memcache with JDO data objects
                    • JDO lifecycle listeners
                      • Defining a cacheable interface
                      • The Connectr application's lifecycle listeners
                  • Summary
                  • Chapter 10: Pushing Fresh Content to Clients with the
                    Channel API

                    • Why use push technology
                    • Implementation overview
                    • Setting up the application to handle pushed messages
                      • Server side channel creation
                        • Under the hood of ChannelServer
                      • Preparing the GWT client for pushed messages
                        • Adding a handler to process pushed messages
                    • Pushing messages to clients
                    • Creating custom classes of pushed messages
                    • Telling the server a client is inactive
                    • Adding a refresh button to allow on-demand news updates
                    • Summary
                    • Chapter 11: Managing and Backing Up your App Engine Application

                      • Configuration and deployment
                        • Configuration
                          • The deployment descriptor—web.xml
                          • Configuring DoS protection blacklists—dos.xml
                          • App configuration—appengine-web.xml
                          • App engine application versions
                          • Application file limits
                      • The Admin Console
                        • Browsing an app version's logs
                          • App server startup latency
                        • Quotas and billing
                          • Monitoring your quota levels and resource usage
                          • Application behavior when a quota is depleted
                        • Adding developers for an application
                      • Command-line administration
                        • Using appcfg.sh
                          • Locating appcfg.sh
                          • Using appcfg.sh
                          • Downloading application logs
                        • Bulk download and upload of an app's Datastore
                          • Downloading data
                          • Uploading or restoring data
                      • Using Appstats
                        • Enabling and configuring Appstats
                        • Browsing the Appstats statistics page
                      • Using your own domain for an app
                      • Summary
                      • Chapter 12: Asynchronous Processing with Cron,
                        Task Queue, and XMPP

                        • Introduction
                          • What the client sees
                          • What goes on behind the scenes
                          • Overview of the chapter
                        • Activity stream classes
                          • The StreamItem persistent class
                            • HTML 'sanitization'
                          • The StreamItem DTOs
                        • Server-Side asynchronous processing
                          • Tasks and Task Queues
                            • Task Queue specification
                            • Task Queue quotas and limits
                            • Monitoring tasks in the App Engine Admin Console
                            • Using application-defined Task Queues
                            • Defining a task: TaskOptions
                            • Some Task Queue design considerations
                          • Cron Jobs
                          • Asynchronous server-side tasks in Connectr
                            • Regular background tasks
                            • Context-Specific feed update tasks
                        • Supporting synchronous content delivery:
                          Datastore queries and caching
                          • Making StreamItem queries fast
                            • Finding StreamItems for all Friends of a user: doing write-time work to
                              make queries fast
                            • Filtering the StreamItems on a subset of the user's Friends: Using key paths
                              and contains()
                          • Stream cache management
                        • XMPP: Information push to the app
                          • The App Engine XMPP service and API
                            • XMPP addresses
                            • Sending an XMPP message
                            • Receiving an XMPP message
                            • XMPP-related quotas and limits
                          • Setting up Connectr as an XMPP client
                            • Subscribing a Connectr app to the XMPP Breaking News Gateway App
                            • Processing the incoming XMPP notifications
                        • Summary
                      • Chapter 13: Conclusion and Final Thoughts


                      Ready to improve your GWT and GAE Java skill?