Play! Framework

In 2004 a framework named Ruby on Rails, or Rails for short, was released and was quickly a widespread success. The greatest change that Rails introduced was a "convention over configuration" approach. A developer could create a new project and be coding in minutes. There have been many such frameworks in the years since Rails saw first light. One of these frameworks is called the Play! Framework. This blog will focus on Play! from a Java developers point of view.

What is Play!

Play! is very different compared to your average Java web application. Play! doesn't follow many of the J2EE conventions or standards. Instead the developers of Play! decided to make the most efficient web framework possible. It's not a full Java Enterprise stack and Play! expressly states that it is built for web developers. This humble developer started out very skeptical that it would be useful and some of the design choices made little sense to my "Java Enterprise" mindset.

So what is Play!? - let's take a look at what it offers at a glance.

  • Completely stateless - matching the HTTP standard
  • Non-blocking IO - reactive, fast
  • Hot-reload of Java classes - more on this later
  • Compiled views - which can be tested
  • Symmetrical simple routes - created with purpose and design
  • Both Scala and Java - Built with Scala but Java is a first class alternative
  • Large third-party module repository - growing daily
  • Commercial Support - by TypeSafe and Zenexity

Favorite Feature

After years of building enterprise applications I was incredibly surprised how easy it was to become productive with Play!. Not just productive but highly productive. Let's walk through how this is done the Play! way.

Getting Started - Basics

Installation is simple, you download a zip file from http://playframework.com/ and unzip somewhere on your machine. Then all you have to do is add an environment variable named PLAY_HOME similar to how you set up JAVA_HOME under normal circumstances. The last thing you need to do is add the Play installation to the execution path of your computer. On my Mac this is all done by opening the file .bash_profile in your home directory and adding:

export PLAY_HOME=/path/to/unzipped/play
export PATH=$PLAY_HOME:$PATH

Once you have installed the framework on your machine you can get down to business. You begin by invoking the play script, which starts the Play! console or in this case creates your basic project. I'm going to create a project called "foo".

This command will create a directory named "foo" with all the basic files the project needs. Next we are going to start the Play console. There are two main options to do this

play run

or

play debug

You are now running the Play! console. Your application is not running yet but fortunately, you don't have to exit the console during development. There are several options to use from here, the most useful of these are:

  • compile - does just what you think it does
  • reload - re-reads all configuration files including build scripts, config files and dependency resources
  • test - runs all unit tests
  • run - starts the bundled netty server so you can run your application

We'll go through these options one by one but firs, let's set up your project in your favorite IDE. Play offers a way to do this as well. Depending on your preference you just type "eclipse" or "idea" in your console and hit enter. Once you have your project open in your IDE you can connect to and debug the application. As you can see from the output above the port to connect to is 9999 to start a debug session. This can be useful when you want to debug the startup of your application.

Compile

This will compile your entire project. As with most tools this compiles your controllers, models and any other traditional code you have in your project. Unlike most other tools it also compiles your asset files, minifying all javascripts and compile less files into css. Unlike all other tools it will also compile your views into runnable bytecode. This is one of the groundbreaking highlights of the Play! framework, more on why further down. Let's look a little at how a Play! project is organized.

Any javascripts placed in the assets/javascripts will be minified and copied to the public/javascripts folder. Same thing goes for your less files. The files above will be available as main.min.js and main.min.css for you to use in your view. You can add any additional property files to the conf folder and read them by either adding an include statement to the application.conf file or

Play.application.resourceAsStream("my.properties")
Reload

When you make changes to config files you need to reload your application. Let's look at that by adding a dependency. You can add any maven dependency to your Play! project. The file named Build.scala is the application build script. It is a Simple Build Tool, or SBT, project file. You don't need to know much about SBT to work with Play!, most of what you need is really simple. Adding a dependency is easy as changing your SBT file to the following.

 
val appDependencies = Seq(
 ...
 "mysql" % "mysql-connector-java" % "5.1.18",
 )

This will add as you probably can tell, the drivers for MySQL to your project. In order for your application to recognize this added dependency you need to run "reload" in your Play! console. To use MySQL you also need to add some configuration properties in your application.conf file. After doing that and issue a new "reload" your application is setup to use your database. Obviously you can make several changes and only issue one "reload". One thing that I find difficult to remember is that every time you add a dependency you need to re-run the idea or eclipse command for Play! to regenerate your project files. AS a reminder, you don't need to exit the console to do so, you can just type the command in the running console and you're done.

Test

All the views are compiled in Play! which means you can call them as methods. In fact, that is how you pass on the flow of your application from Controller to View. You just call the static method on the class of your view. The same thing goes for testing the view.

import static play.test.Helpers.contentAsString;
import static play.test.Helpers.contentType;
 
@Test
public void indexShouldHaveCorrectTypeAndTitle() {
 Content html = views.html.index.render("Some Title");
 assertThat(contentType(html)).isEqualTo("text/html");
 assertThat(contentAsString(html)).contains("Some Title");
}

As you can see, the execution of the view file index's render method returns a Content object, which in this case will be of the subtype Html. This object is the rendered HTML result of your view. To run all your tests all you do is issue the command "test" in the Play! console. There are several other neat features in the Play! test suite, for example, Selenium bundled in for running complete scenarios in your application.

Run

Now, if you are ready to run your application, all you do is type "run" in the console. Your application will be waiting for you at port 9000. With your application running, open the file Application.java in package controllers and change it to this:

public class Application extends Controller {
 
 public static Result index() {
 return ok(index.render("Hello World!"));
 }
 
}

Then open the view file index.scala.html and change it to this:

@(message: String)
 
@main("My Super Awesome Play! Application") {
 @message 
}

Open your browser and go to http://localhost:9000/ and you will see this:

This is because, as it says, we have a duplicate resource. The basic project already has a main.css so our main.less can't be copied to the public folder. This also demonstrates how clearly Play! will show you errors in your application. It will pinpoint the row where there is a compile problem or where there is an exception being thrown. Fix this by removing the main.css from the public folder, reload your browser and you should see this instead (with some additional css styling):

Summary

You will have a hard time finding any framework that is more productive than Play!. How much time have you spent recycling a container? Endless minutes spent making a small adjustment, starting the server, waiting, waiting, waiting and then finally getting to test the change you made. Just to do it again. Add to this the fact that it takes seconds to get a project up and running. Personally I think Play! is the future of web development on the Java stack. Not every project is suited for the full enterprise treatment, in fact, a lot of times it is overkill. That's where Play! shines.

In my next blog I will show a few view related tricks I have picked up during my time learning Play!