An interesting gotcha in Java unittesting
Posted by Nick Johnson | Filed under java, unittesting
Those of you who have more than a passing familiarity with Java will be aware of Java's semantics for object equality using '==': it returns true iff the two arguments are the same object. There's no operator overloading for the equals operator, even by built in classes; classes that want to do value equality tests are expected to override the built in 'equals()' method.
This leads to a common pitfall with Strings. The following compiles fine, with no warnings:
public static void isFoo(String s) { return s == "foo"; }
This won't work as intended, of course, because it will only return true if the passed in string is the very same object as our string literal "foo". Let's write a unittest to make sure everything works as expected:
@Test public void testIsFoo() { assertTrue(Blah.isFoo("foo")); assertFalse(Blah.isFoo("bar")); }
But wait! This test passes just fine! Something is very wrong here.
What's happening is that the Java compiler is interning string literals, so that multiple uses of the same string constant point to the same actual string object at runtime. This saves memory, but it's making it tough for us to test properly. You might ...
Demystifying the App Engine request logs
Posted by Nick Johnson | Filed under python, app-engine, java, logs
People often ask about the App Engine request logs shown in the admin console: What do all the fields mean? How should they be interpreted? They're actually fairly easy to read once you know the format, so here's a quick-reference to help.
The basic format is based on the Apache combined log format, which is so widely used even outside Apache that it's become a de-facto standard of sorts for webserver request logs. In addition to that, App Engine adds a number of extra fields logging additional, App Engine specific stats. Suppose you're examining the following log entry:
107.10.42.191 - foobiz [10/May/2011:17:26:28 -0700] "GET /page.html HTTP/1.1" 500 2297 "http://www.example.com/home.html" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; en-us) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4,gzip(gfe),gzip(gfe),gzip(gfe)" "www.example.com" ms=364 cpu_ms=23 api_cpu_ms=0 cpm_usd=0.001059
Here's what the fields mean, in order:
- Client's IP address (107.10.42.191)
- The RFC1413 identity of the client (in practice, always '-')
- The userid determined ...
Google I/O playlist, day 3: What's hot in Java for App Engine
Posted by Nick Johnson | Filed under channel-api, google-io, java, google-io-playlist
This is the third in a series of posts providing a day-by-day playlist to help break up the Google I/O session videos - specifically the App Engine ones - into manageable chunks for those that haven't seen them.
Today's video is "What's hot in Java for App Engine" by Don Schwarz and Toby Reyelts. It provides an overview of the first year of Java support on App Engine, focusing on a demo app that shows off a number of features of the Java runtime.
At first glance, this is definitely a talk for the Java programmers amongst us, and it certainly has a lot of content on those lines; the demo shows off to good advantage a number of the App Engine APIs. The secret hidden surprise, though, is something that will be of interest to nearly everyone: Details about the forthcoming channel API. The channel API implements the promised support for Comet on App Engine. For the juicy details, jump to 10:49, and keep watching up to 15:10. There's more details in Moishe's talk on building Real-time Webapps in App Engine, the video for which will be going up later today, and which ...
Authenticating against App Engine from an Android app
Posted by Nick Johnson | Filed under java, app-engine, tech, android
Many an Android app requires a server backend of some sort, and what better choice than App Engine? It's free, reliable, and does everything you're likely to need in a backend. It has one other major advantage, too: It supports Google Account authentication, and nearly all Android users will already have a Google Account.
So given that we want a backend for our app, and given that we want to have user authentication, how do we go about this? We could prompt the user for their credentials, but that seems less than ideal: the Android device already has their credentials, and users may not trust us with them. Is there a way we can leverage an Android API to take care of authentication? It turns out there is.
Authentication with App Engine, regardless of where you're doing it, is a three-stage process:
- Obtain an authentication token. This can be done with ClientLogin for installed apps, for example, or with AuthSub for a webapp. When logging in directly to an application, this is the part of the login process where your user sees a Google signin screen.
- Take that authentication token, and use it to obtain an authentication ...
App Engine Java API call hooks
Posted by Nick Johnson | Filed under coding, app-engine, tech, java
In a previous post, we discussed API call hooks for Python. It's possible to hook and modify RPC calls in Java, too. In this post, we'll demonstrate how.
All API calls in Java are handled by the class com.google.apphosting.api.ApiProxy. This class behaves similarly to the ApiProxyStubMap in the Python SDK, having makeSyncCall and makeAsyncCall functions that take care of invoking the relevant API calls. Unlike the Python runtime, however, all Java API calls are handled by a single delegate class, defined by the interface ApiProxy.Delegate. The active delegate for an App Engine app can be retrieved with ApiProxy.getDelegate, and set with ApiProxy.setDelegate.
Another difference from the Python API is that API calls are serialized into byte arrays before being passed to the ApiProxy, and responses are likewise deserialized by the caller. As a result, the makeSyncCall method takes a byte array as an argument, and returns a byte array.
Because all calls are routed to a single Delegate, the granularity of hooks supported is restricted to hooking all API calls, or none. To make things easier, we'll define a Delegate implementation that dispatches API calls to other Delegate subclasses based ...
Server-side JavaScript with Rhino
Posted by Nick Johnson | Filed under coding, app-engine, cookbook, tech, java
I've only made limited use of the Java runtime for App Engine so far: The two runtimes are largely equivalent in terms of features, and my personal preference is for Python. There are, however, a few really cool things that you can only do on the Java runtime. One of them is embedding an interpreter for a scripting language.
Rhino is a JavaScript interpreter implemented in Java. It supports sandboxing, meaning you can create an environment in which it's safe to execute user-provided code, and it allows you to expose arbitrary Java objects to the JavaScript runtime, meaning you can easily provide interfaces with which the JavaScript code can carry out whatever actions it's designed to carry out.
Rhino also supports several rather cool additional features. You can set callback functions that count the number of operations executed by the JavaScript code, and terminate it if it takes too long, you can serialize a context or individual objects and deserialize them later, and you can even use continuations to pause execution when waiting for data, and pick it up again later - possibly even in another request! Hopefully we'll show off some of these features in future ...