Tue, 15 Nov 2011

Using Scala and the Play Framework in Windows Azure

The Devoxx conference is running this week in Belgium. Be sure to check out the Windows Azure booth there. I didn’t make it to the conference, but I volunteered to build a demo application for the booth that would show attendees a real example of running Java in Windows Azure. As I was brainstorming what to do, I browsed through the Devoxx schedule. I noticed that there are a few mobile clients for browsing the schedule. This observation quickly lead me to the schedule API.

I decided it would be fun to build my own schedule browser in Windows Azure, but I didn’t know where to start. (I’m quite out of date with what’s happening in the Java world.) Reading the Devoxx schedule, I spotted a talk about the Play framework (which has an option for building in Scala), and I was quickly hooked. After a day of coding, I had built http://devoxx.cloudapp.net. The full source code is available at https://github.com/smarx/devoxxschedule.

How It Works

I won’t go into the Scala and Play framework parts of the code. The framework is a fairly straightforward MVC framework that should be comfortable for most web developers. Scala was a new language for me, and I apologize in advance if my code is ugly. I like the functional style of Scala but was unsure of some of the idiomatic ways to do things that I’m used to doing in C# with LINQ.

As for the Windows Azure part of the code, I was fortunate in that the Play framework includes some simple commands for running an application. To run an application in development mode, play run is all that’s required. To run it in production, play run --%prod. Once I realized that deployment would be as simple as executing the right command, I was able to reuse my packanddeploy project (which I blogged about a few weeks ago) to get things running.

A Few Tricks

For the most part, running the app in Windows Azure was straightforward, but I thought I’d share the few places where I learned something.

Using Blob Storage from PowerShell

To keep the deployment package small, I quickly moved away from packaging the Java runtime and Play framework with my cloud app and instead opted to keep those in blob storage and download them at runtime. I’ve used this technique before, but this time I decided to use the .NET storage client library from PowerShell (so I didn’t need to make my copy of the JDK and the Play framework public). This code was a bit interesting, mostly because I’m not too familiar with PowerShell syntax. Take a look at WorkerRole\downloadstuff.ps1 in the source to see how this works.

There are probably better ways to accomplish what I was doing here. Notably, the Windows Azure Bootstrapper (from Cumulux) could probably accomplish this in a single command. In retrospect, I probably should have just used that.

Specifying an IP Address to the Play Framework

The Play framework provides a nice command-line argument, --http.port to use a specific port, but with Windows Azure SDK 1.5 and beyond, we also need to use a specific address. (The compute emulator tries to keep the port constant by using different addresses as needed.) This was less obvious, but I eventually figured out that the Java-style -Dhttp.address parameter would do the trick.

The Home Path on Windows

If you read WorkerRole\run.cmd in the source, you’ll see that I’m passing -Duser.home to force a specific home directory for the user. I found that without this, some code in Maven ended up looking at the path C:\</code> and was unable to find/create the directory it needed. I suspect the need for this has something to do with the user Windows Azure creates on role instances. This was a fairly tricky one to track down, and I suspect it applies to more Java frameworks than just Play.

Resolving Play Framework Dependencies

I found that, despite already having the dependencies, I needed to ask Play to resolve them again by running play dependencies. This is presumably because the paths changed when I deployed to the cloud (as opposed to the paths on my local computer). If you read WorkerRole\run.cmd, you’ll notice that I’m using the call command in the batch file to invoke play. This ensures that control returns back to my batch file instead of moving permanently over to the play batch file.

Environment Variables

You’ll see a lot of environment variables (like JAVA_PATH, PORT, ADDRESS, and CONNECTION_STRING) used in the batch files. Those come from the cool xpath stuff in SDK 1.5 and up. See ServiceDefiniton.csdef for where they come from.

Full Source

This was a fun project to do, and I hope it helps those of you who are experimenting with Java on Windows Azure, particularly if you’re looking to use the Play framework.

The full source code is available at https://github.com/smarx/devoxxschedule.