The Java App Engine SDK provides a fantastic local environment that runs your applications simulating all the services the cloud environment has. This local environment can be of great value to developers and can significantly reduce the time to market of your applications, some of the highlights are:
- Very easy to set up and use, you don’t even have to configure the database!
- Provides full debugging capabilities, including breakpoints, watches, stacktrace, etc., fully integrated with the Eclipse IDE.
- Deploys are virtually instantaneous. Deploys to the cloud environment take some time, and developers want to run their applications quickly to do some functional test and confirm the behavior implemented.
- Deploys to the cloud environment may impact other users and developers, and it is a good practice to make sure that what you deploy passes some preliminary test in an environment that does not affect others before deploying.
- Some activities like loading test data is much easier and faster when done locally.
- Access to the logs in the production environment is great, but they require using a web browser. When running locally, logs are in your development tool console and local files, therefore you can use your favorite log analysis tools to find and filter things to help understand what is going on inside the application.
With all this power and ease of use it is easy to get carried away. It is very important to keep in mind that the local environment is NOT the cloud App Engine environment. If a developer does not understand the differences between these he or she could very easily create an application that works locally but not in production.
And why is that? Well, let me give some examples:
- Production a multi-tenant environment and it imposes restrictions on applications so they don’t monopolize the resources that are shared with thousands of other applications. Google calls these restrictions quotas (for more information on App Engine quotas go to: http://code.google.com/appengine/docs/quotas.html). The local environment does not enforce those quotas. For example, if you create a URL fetcher that downloads more than 1 mb of data from a web source it will work locally, but fail on the cloud environment.
- Requests to your applications are not handled by a single server, but by a cloud of servers. For instance, if a static field is initialized in a request, on subsequent requests there is no guarantee that it won’t be null because the request can go to a different server and run in a brand new virtual machine.
- Production App Engine requires indexes to perform database queries (for information on queries and indexes go to: http://code.google.com/appengine/docs/java/datastore/queriesandindexes.html), if an index does not exist, or it is not in a “Serving” state (i.e. it is a new index that is being built) the query will fail. The local environment by default creates missing indexes transparently for you.
My suggestion is to study and understand the differences between the two environments and implement code that takes those into consideration. Use the local environment specifically for development. Do all your unit testing, test your functionality, and do your debugging locally but never assume a feature is ready to release until you deploy and test it on the cloud environment.