Imagine a bacon-wrapped Ferrari. Still not better than our free technical reports.
See all our reports

The Curious Coder’s Guide to Java Frameworks – Play

Get the full report

Psst! Want to see the 8 most popular Java Web Frameworks compared? Since this post here, we’ve made The Curious Coder’s Java Web Frameworks Comparison: Spring MVC, Grails, Vaadin, GWT, Wicket, Play, Struts and JSF. Grab the complete report in HTML and/or PDF. Win!

See how *Play* ranks in the Full Report


This is our sixth and final individual post in the Rebel Labs review of Java web frameworks, having already covered Vaadin, Grails, Spring MVC, Wicket and Google Web Toolkit (GWT). Today we look at the Play Framework, a nimble compilation of a build tool, application server, web framework, and testing tool. According to our latest Developer Productivity Report, Play has 8% of the market share as a framework and Simple Build Tool (SBT) has a 6% usage rate amongst respondents.

Quick Intro (TL;DR)

Play is a really exciting framework that tries to add Ruby on Rails-like functionality to Java and Scala, such as rapid prototyping, scaffolding, and a convention over configuration paradigm. Play is more than just a framework, Play comes with SBT, Netty (an apache-licensed NIO-based application server), ORMs (Anorm for Scala and Ebean for Java), a templating engine based in Scala, and a ton of core functionality that developers have come to expect in a first tier framework.

The fastest way to get up and running with a basic Play application is to follow the getting started documentation on the Play Framework site. There are also lots of great tutorials on the web, there are even some great and freely available screencasts introducing Play.

What is the Play Framework?

The Play Framework is actually a collection of useful tools and utilities that provide an ecosystem to enable rapid prototyping a la Ruby on Rails, but is also flexible and mature enough to be considered for serious work as well. The Play framework ecosystem contains elements of everything from the build process (SBT) through testing (JUnit and FakeApplication) all the way to running your applications (Netty) on top of the normal niceties of a modern framework. Play is also interesting because it gives you, the developer, the option of a combination of Java and Scala. You are free to use whichever type of project you feel is appropriate for your goal and can even mix raw Java into Scala projects.

Play is based on Akka, which is one of the reasons it’s so great for serious work (you’ll be handling high throughput in no time). Play has a command line interface that is similar to Rails or Spring’s Roo and is very useful in rapid prototyping and initial configuration of projects.

Getting Started

Play unlike most frameworks is not simply a jar to be added to a project’s classpath. Instead it has a binary distribution available from the downloads section of the Play framework site. Then you need to add the play script to your $PATH so it is accessible from your workspace directories.

You should see something similar to this when you type 

$ play help

 into your terminal or command prompt.

Then following the getting started tutorial for Java or Scala is a great introduction to the framework as well as deploying Play to Heroku.

Play in action

Play is pretty quick to get up and running, in a matter of minutes a developer can get a deployable CRUD application developed just from the tutorial alone. A lot of this comes from the Ruby on Rails roots of Play, namely scaffolding and convention over configuration.

Editing the conf/routes file allows you to create RESTful actions for your application. Some example actions are:

# Home page
GET     /                       controllers.Application.index()
 
# Tasks          
GET     /tasks                  controllers.Application.tasks()
POST    /tasks                  controllers.Application.newTask()
POST    /tasks/:id/delete       controllers.Application.deleteTask(id: Long)

There are also really cool features built into the core of Play, like native JSON parsing:

import org.codehaus.jackson.JsonNode;
import play.mvc.BodyParser;
...
 
@BodyParser.Of(BodyParser.Json.class)
public static Result sayHello() {
  JsonNode json = request().body().asJson();
  String name = json.findPath("name").getTextValue();
  if(name == null) {
    return badRequest("Missing parameter [name]");
  } else {
    return ok("Hello " + name);
  }
}

and a built in templating engine based on Scala (inspired by ASP.NET’s Razor):

@(customer: Customer, orders: List[Order])
 
<h1>Welcome @customer.name!</h1>
 
<ul> 
@for(order <- orders) {
  <li>@order.getTitle()</li>
} 
</ul>

Actors and Akka

One of the most powerful and hardest to understand features in the Play framework is the Akka Actor Model system integration. Akka Actors are incredibly useful for creating highly scalable and concurrent applications. This works on the premise of the notion of Future and the type safe declaration of Promise blocks. These features allow developers to asynchronously run multiple processes at once to help create highly scalable applications, which is a definite plus as more applications are being used with big data sets.

import static akka.pattern.Patterns.ask;
import play.libs.Akka;
import play.mvc.Result;
import static play.mvc.Results.async;
import play.libs.F.Function;
 
public static Result index() {
  return async(
    Akka.asPromise(ask(myActor,"hello", 1000)).map(
      new Function<Object,Result>() {
        public Result apply(Object response) {
          return ok(response.toString());
        }
      }
    )
  );
}

and another example, this time showing the scheduling functionality of Actors:

Akka.system().scheduler().schedule(
  Duration.create(0, TimeUnit.MILLISECONDS), //Initial delay 0 milliseconds
  Duration.create(30, TimeUnit.MINUTES),     //Frequency 30 minutes
  testActor, 
  "tick",
  Akka.system().dispatcher()
);

Testing using Play

One of the coolest things about the Play framework is the focus and attention to testing applications. By default, Play framework applications should use JUnit for testing with more natural language assertions:

package test;
 
import org.junit.*;
import play.mvc.*;
import play.test.*;
import play.libs.F.*;
import static play.test.Helpers.*;
import static org.fest.assertions.Assertions.*;
 
public class SimpleTest {
    @Test 
    public void simpleCheck() {
        int a = 1 + 1;
        assertThat(a).isEqualTo(2);
    }
}

JUnit is pretty useful and the extra assertions make unit testing less painful (more on Unit Testing from Rebel Labs), however every developer has run into the problem of needing an actual application up and running to test various pieces of functionality and Play can accommodate that need easily using the FakeApplication.

@Test
public void findById() {
  running(fakeApplication(), new Runnable() {
    public void run() {
      Computer macintosh = Computer.find.byId(21l);
      assertThat(macintosh.name).isEqualTo("Macintosh");
      assertThat(formatted(macintosh.introduced)).isEqualTo("1984-01-24");
    }
  });
}

And you can even test the extra non-programming pieces of you applications, such as templates:

@Test
public void renderTemplate() {
  Content html = views.html.index.render("Coco");
  assertThat(contentType(html)).isEqualTo("text/html");
  assertThat(contentAsString(html)).contains("Coco");
}

Time to express our feelings

Our impressions of Play are not merely those of observers only; we actually use Play heavily in our own development at ZeroTurnaround. We find Play to be a very robust and well thought-out framework with lots of room to… “Play” around by introducing more functional and asynchronous aspects into our Java and Scala applications (yes, pun intended).

We recommend Play for those interested in rapid prototyping as well as developers eager to explore more concurrent methodologies for their applications. But as nothing is perfect, there are some disadvantages…and one of the downsides of Play is the variability in what constitutes the Play framework between revisions. Play 1.x and 2.x are incredibly different and entire pieces of the environment have been swapped out and reworked between the different versions. There is a migration guide available at the Play framework site.

Nevertheless, we don’t think that backward incompatibility should scare prospective curious coders from trying out the Play framework, namely because we do not foresee backward incompatible changes in future versions, and the Play framework is very stable as is.

We hope you’ve enjoyed this overview of the Play framework, and invite you to look for the full Rebel Labs report on Java frameworks in the coming weeks, which will go a few steps further in our tests and reviews. In the meantime, stay tuned @RebelLabs on Twitter, and please leave comments below. After all, devs are opinionated, right? ;)