Google has broadened their Google App Engine (GAE) support to include Java in addition to Python. This addition brings a large set of Java ecosystem related tools, frameworks, and languages (like JRuby and Clojure) along for the ride. However, it also imposes a number of limitations on the GAE Java applications to further Google's ability to scale and cluster them with minimal effort. The official Google blog summarizes the introduction of Java support by saying:

...We wanted to give developers something that they could be ecstatic about, but we knew we would have to marry the simplicity of Google App Engine with the power and flexibility of the Java platform. We also wanted to leverage the App Engine infrastructure -- and by extension Google's infrastructure -- as much as possible, without giving up compatibility with existing Java standards and tools. And so that's what we did. App Engine now supports the standards that make Java tooling great. (We're working on the tooling too, with Google Plugin for Eclipse). It provides the current App Engine API's and wraps them with standards where relevant, like the Java Servlet API, JDO and JPA, javax.cache, and javax.mail. It also provides a secure sandbox that's powerful enough to run your code safely on Google's servers, while being flexible enough for you to break abstractions at will...

CNet notes that GAE is running Java 6. However, as mentioned above a number of limitations have been imposed to constrain Java to fit the GAE model. GAE Java is based on the Java 2.4 Servlet API:

Once a request is sent to the client no further processing can be done. This includes data streaming.

A request will be terminated if it has taken around 30 seconds without completing. At this point an exception is thrown. If not caught a 500 error is returned to the user.

Moving up the stack are several sandbox restrictions:

Applications can not write to the file system and must use the App Engine datastore instead.

Applications may not open sockets

Applications can not create their own threads or use related utilities such as timer.

java.lang.System has been restricted as follows:

exit(), gc(), runFinalization(), and runFinalizersOnExit() do nothing.

JNI access is not allowed.

In addition to these key items there are other limitations such as a JRE class loading white list. From the documentation GAE seems to impose a good deal of its magic using custom classloaders. However, they should allow other application level classloaders as long as they can operate with the above restrictions.

The next logical question is what do the above restrictions provide the user in terms of GAE application benefits. The first is scalability. App Engine uses multiple web servers to run your application, and automatically adjusts the number of servers it is using to handle requests reliably. A given request may be routed to any server, and it may not be the same server that handled a previous request from the same user. The documentation notes:

...An application can process around 30 active dynamic requests simultaneously. This means that an application whose average server-side request processing time is 75 milliseconds can serve up to (1000 ms/second / 75 ms/request) * 30 = 400 requests/second without incurring any additional latency. Applications that are heavily CPU-bound may incur some additional latency in long-running requests in order to make room for other apps sharing the same servers. Requests for static files are not affected by this limit...

Google has also provides a BigTable backed version of JPO and JPA and a Google Plugin for Eclipse facilitating easier GAE development.

Google has let a number of developers play with GAE for Java while it has been in development. Paul Hammant took it through its paces and had a number of observations:

...Be aware also that multiple concurrent requests from the same client are not going necessarily hit the same servlet container at the back end. It is all apparently from the same domain name (there is no resource forwarding going on), but the there most likely will be different servlet container instances responding to the requests. This is not going to be a problem for a correctly written stateless app, but one that leverages the session for storing attributes might experience concurrency issues from two writes of to the same logical resource within that apparent map... ...Google have implement a very thorough sandbox. Its no doubt to protect them from malicious code ... XStream is one that is particularly beloved of a section of the Java community. The latest version is 1.3.1 and on initialization anywhere within the realm of GAE is throws exceptions.

Other engineers were able to get Clojure, JRuby, and Groovy working. ThoughtWorks Ola Bini has a detailed blog post on GAE's handling of dynamic languages.