Impressions of working with Play! Framework 2.1 + Java

    There was the fourth week of heavy fighting with Play! Framework 2.1 + Java. Victory was approaching inexorably, but it was far from complete surrender.
    After encouraging news about the development of Play! 2.1, for example on LinkedIn , it was decided to try it in one new project. To test it, so to speak, in action. What came of it? I would say that it was a small war between me and Play! 2.1. Why? Details under the cut, but for the impatient:

    Brief conclusion

    For the assault it was necessary to take a secret weapon, codenamed Scala. If you come face to face with Play! Framework 2.1 and shout with all your might: “You are a Scala framework!”, Then he will be afraid of such directness and modestly open his doors to the world of great opportunities.
    “Don't Know Scala?” - “Use Play 1.2.”
    “Well versed in Scala?” - “Be sure to try Play 2.1. But still be patient. ”


    For 7 years with a mouse and keyboard with a sword and shield, I have visited different countries on the planet Java. These were the ancient ruins of Enterprise, where life is still warm, and blooming Springland, and his vassal Grouvilandia with the capital in the Grails City, and once the advanced and exotic Pleiterra Pervoe, and many, many other states, cities and even remote villages. But the campaign on Pleiterra II was unexpectedly difficult.
    For about 9 months I worked on one project using Play 1.2.x, and was absolutely delighted. Even after Spring Framework 3, it seemed like the pace of development speed and simplicity, not to mention the monstrous Java EE 5 + JSF.
    Then there was a short break, during which I managed to work intensively with Grails 2.x for 3 months and understand how Java lagged behind Groovy in terms of convenience and syntax capabilities. And that Grails is somewhat easier and faster to develop than pure Spring Framework 3 + Java.
    However, it was time to choose a framework for a new project, and the choice fell on Play 2.1. Was this the right decision? Interesting for sure, but the right one - it will still show time.
    In the meantime, I want to share my impressions of working with Play 2.1. There will be many comparisons with Play 1.2.x, moaning about Java and emotions. There will be almost no code, and generally accepted terms and concepts will not be translated into Russian. For example, stateless framework .


    Lack of documentation

    The maps provided by the rulers of Playterre II were far from complete. The main roads are indicated quite accurately, but around these roads impassable thicket. In order not to stray, I had to grab the locals and ask them a lot of questions. By the way, they answered very willingly.
    The official documentation is rather stingy. There are two books Play 2 with Java and Play 2 with Scala . The first, about Java, largely repeats the official documentation with comments for beginners. The second, about Scala, is a little more useful and covers the necessary topics, for example, Chapter 8. Building a single-page JavaScript application with JSON.
    Of course, there is a large and active community, you can ask for help and ask a question both on Google Groups andStackoverflow . But the pleasure of developing is somewhat lost if you constantly have to look for answers to seemingly simple questions.
    I even participated in improving the documentation ( here ), but there are still many places that I want to cover in more detail.
    For Play 1.2.x, the documentation was more complete and more useful. Searching on Stackoverflow and Google Groups only had really unusual things to do.

    Compilation speed

    The roads here are far from ideal. Sometimes I had to ride for hours, drowning in the mud and begging the horse not to give up and ride faster. The transfer of a large army takes a very long time. Checkpoints and checks are everywhere on the roads.
    For many, this will not be news, but compilation here is slow. Much slower than in Play 1.2.x. I understand that almost everything compiles here, from simple Java classes to Scala temlates and coffee scripts. But this is a long time. Let sane error messages be issued, but this is a long time. Lightning fast ideally Hit refresh workflow stalls and annoys.

    Work with the database

    Well-known residents do not know how to finish building their own fortresses. They can’t say: "Erect another tower, but quickly!". Not. They need a detailed plan.
    There is a built-in Database Evolutions engine. But there is a problem with the generation of these scripts. Ebean can still create a complete script, but there are already problems with incremental ones. jpa.ddl=updateUnfortunately, I did not find an analogue for Ebean. If someone tells me, I will be immensely happy. An analog or adaptation of LiquiBase's Diff would also be very helpful.

    The hired foragers turned out to be strange men. It seems to work, but you are constantly waiting for supply disruptions.
    Ebean as a concept is extremely good. The main advantages:
    • lack of sessions (Session, EntityManager, etc.), which fits well with the stateless framework. However, as such, there is a Persitent Context.
    • Partial Objects support for writing more efficient queries.

    Controversial issues:
    • Partial JPA support. You need to know and understand exactly where this support ends.
    • Lack of documentation and examples of use.
    • Not such an active development and not as large a community as Hibernate.

    There are transactions here too. You can even mark the controller method as @Transactional. But only the controller method or the controller itself. For third-party classes, you must already take care of this yourself.
    In general, Ebean is a very interesting library, sometimes even simpler and more understandable than Hibernate or JPA, but I can’t get rid of doubts that there are enough possibilities to satisfy all the needs of a growing project.
    Of course, you can use the standard JPA, but this is not enough Model.find("byName", name)from Play 1.2.x or integration with Spring Data JPA 1 . There is a feeling that you are returning to the past for several years.

    By the way, Ebean has several significant drawbacks: you can read more about them in the Caveats section on the pageUsing the Ebean ORM . And the fact that Play 2.1 stops generating getter / setter, if the class has at least one such handwritten method, makes it necessary to avoid the names of methods starting with c getor set. For getters, I now just omit the word getand call methods byNameor byEmail.

    But such an incredible thing, you can even say the killer feature in Ebean, as the PagingList in the stateless framework is not applicable. Alas and ah.

    As for working with NoSql databases, you can easily find plugins for Elasticsearch, MongoDB (even a few pieces) and OrientDB. I haven’t used it myself, so I can’t say anything about the quality of these plugins.


    Checking the state of the army is constantly frustrated by enemy spies. Local animals interfere with the organization of the exercises: monkeys throw coconuts, ivy braids their legs, and sometimes kamikaze skunks are found.
    It is, there are many possibilities: from simple unit tests of models to testing controllers and using Selenium.
    In my tests, I tried to use the in-memory database as described in the documentation:
    public void setUp() throws Exception {

    However, I immediately had two problems, big and small.

    Small: how to deal with transactions in tests? Nothing of the kind @Transactionalfrom Spring or Grails I found. It remains only to open and roll back transactions in tests yourself. Inconvenient and immature.

    The big one: the conflict between the fact that the main base is MySql, and for the in-memory H2 tests. So, H2 refuses to understand evoluation scripts for MySql, but using a non-default database configuration, for example like this:

    entails the uncertainty of where the data will still be stored if you use the method save()without specifying the configuration.
    I saw several vague descriptions of the solution to this problem, but simplicity does not smell there.
    The official documentation about how to organize the work of the database in tests does not say anything.

    Of the good. There are useful commands ~testor ~test-onlythat will work every time you change the source code. Saves time needed to run tests.


    There are only the simplest armor in state forges. Craftsmen forge much better things.
    Authorization and authentication capabilities remained at Play 1.2.x. There is an Action Composition with annotation @With, there is a Security.Authenticatorgood example of how to use it: the Adding authentication page , the Implementing authenticators section.
    Third-party plugins offer more features. For example, Deadbolt or SecureSocial , but they seemed too tightly wound up for a small project, and I perfectly managed with my handwritten authorization.
    By the way, this is surprising, but Play 2. 0 has lost such a useful feature asAuthenticity Token , but there is a third-party plugin that makes up for lost abilities. However, in Play 2.1, some were added filters, which are mentioned in the press release of version 2.1, but about which there is very little documentation. Among the filters just mentioned CSRFFilter. The only thing that was found about him was this post , which describes how to work with a filter to protect against CSRF in Scala. How to apply and whether it applies in general to Play 2.1 + Java still needs to be figured out.


    Sometimes mirages came across on the way. As they approached, they disappeared. There were no mirages on the maps.
    Several times, a fully working code stopped working! Apparently, compilation and generation of getters / setters does not always work correctly. Helped play cleanand restart the project.
    The strangest thing I stumbled upon was that the JDK 7code type was valid for :

    catch (IndexOutOfBoundsException | ArrayStoreException e)

    brought Play 2.1 to a complete stupor: no errors, no messages, just the server freezes on these lines and nothing happens further. Asked a question here , waiting for an answer.


    Here such swamps come across that they can suck headlong. And they may not suck.
    I must say bluntly: for the effective use of templates you need to know Scala well or at least understand something in it. Otherwise, all this turns into an incomprehensible trick of the code. And you have to be very careful, because it works like this:
    @main(title = "Home") {    

    Home page


    and so there will already be an error due to {on a new line:
    @main(title = "Home") 

    Home page


    Or another example:
    //так работает
    @if(user == null)
    //а так нет, потому что стоит пробел:
    @if (user == null)

    When I first read about Scala templates in Play 2.0, I was very happy because it looked like a very convenient Razor from .Net. It really looks like, and, in my opinion, more convenient than many template engines in the Java world. However, do not forget that you must declare all input parameters as the first line. And fullNameyou can only declare a variable in the code like this:
    @defining(user.getFirstName() + " " + user.getLastName()) { fullName =>
    Hello @fullName

    And what to do import for some things: @import helper._. And many more “ifs” and “buts”, within which you feel not very free.
    The main plus is Scala templates are compiled and checked at the compilation stage, which reduces the number of unsolicited errors and offensive typos.
    In general, whether the Scala template is good or bad in Play 2.1 is a moot point, but it recedes into the background, because Javascript MVC frameworks are gaining popularity, and the following becomes relevant:

    Work with JSON

    Then the brave warrior was generally upset and went to drink in a tavern.
    In my opinion, Play 2.1 loses to Play 1.2.x. The main reason is that instead of Gson, Jackson is used as the main library for working with JSON in Java. I liked working with GSON in Play 1.2.x, it was convenient and flexible. Jackson needs to be worked in a completely different way. Apparently, I have not yet reached that level of understanding of Jackson in order to enjoy him. And the fact that the field names in the JSON string should be escaped with double quotes caused me a heavy sigh:
    return ok(Json.parse("{\"status\": \"success\"}"));

    There is almost no readability. Especially when compared to the ease of working with JSON in Grails:
    render([result: 'fail'] as JSON)

    Of course, not everything is so bad, but the best thing you can do in Java is something like 2 :
    ObjectNode result = Json.newObject();
    ArrayNode arrayNode = result.putArray("photos");
    for (Photo photo : photos) {
        ObjectNode photoAsJson = arrayNode.addObject();
        photoAsJson.put("guid", photo.guid);
    return ok(arrayNode);

    Quite tolerable.
    However, for Scala, JSON support in Play 2.1 has been significantly improved:
      "users" -> Json.arr(
          "name" -> "bob",
          "age" -> 31,
          "email" -> ""  	  
          "name" -> "kiki",
          "age" -> 25,
          "email" -> JsNull  	  

    But in Groovy, it still looks shorter and simpler. It is hoped that Scala will nevertheless add native JSON support, as it is now for XML.
    I decided to simplify my life, I added two additional classes with static methods: one is the Pairanalog Tuple2from Scala, the other is the class that puts Pairs in Map. As a result, it became easier for me:
    return ok(toJson(map(
                        pair("status", "fb-logged-in"),
                        pair("user", map(
                                pair("facebookUserId", fbUser.facebookUser.userId),
                                pair("fullName", fbUser.fullName())

    Since we are talking about tuples ( Tuples), then in Play 2.1 support for functional for Java is copied from Play 1.2.x, a library play.libs.F. However, there is no mention in the official documentation about this. We must look docks for 1.2.x the Play .

    And one more thing: XML support also migrated from Play 1.2.x, and play.libs.XPathit’s very convenient to use XML.

    Work with mail

    The carrier pigeons and crows are all imported here. It’s easy to get them. And it is rumored that the rulers of Pleiterre II shot all the birds themselves.
    I want to say a few words about mail because there was built-in support for sending mail in Play 1.2.x, but not in Play 2.1. There is an official plugin for mail . Here they say that the creators themselves decided not to add mail support. Allegedly, it is so easy and simple that everyone can do it for himself. A lot of questions and indignation in Google Groups refutes this point of view: people expect from Play 2.1 no less functionality than it was in Play 1.2.x.


    If earlier contracts were written on scrolls, now on separate leaves.
    The main thing worth noting is that they were removed framework ID. Now, instead of one large configuration file, you need to have several separate ones. Controversial point, each approach has its pros and cons. If it used to be for launch production:
    play run --%production
    now it looks like this:
    play -Dconfig.resource=prod.conf start
    And it prod.confcontains all the overrides of settings without any prefixes.

    IDE Integration

    My best horse tucked his foot on the local roads!
    I won’t tell you for all Odessa for all IDEs, but my beloved Intellij Idea has support for Play 2.x far from ideal. Code navigation very often leads to generated classes that you don’t need to look and see, sometimes there are problems editing scala templates, full SBT support will be available only in version 13. Here are just what I found and reported myself: There is little
    pleasure in writing code. I understand that Play 2.x was released not so long ago and may not be as popular as to spend large resources on its support in the IDE. Just be aware that you should not expect much help from the IDE.
    With Play 1.2.x, this is much better.

    Simplicity gone

    If the country of Playterre I was full of miracles and much was done with a wave of a magic wand, then in Playterra II there is no magic, only a shovel and a hoe, a shield and a sword.
    Play 1.2.x was very simple and convenient. Much was done somehow by itself, and it worked. Yes, I heard opinions that too much happened in Play 1.2.x, too much was generated and was completely unlike the usual Java world, but it worked simply, easily and quickly. All the complexity was hidden from ordinary users, and only the most meticulous programmer had to dig into the intricate source code.
    In Play 2.1, almost all the "magic" is left to Scala. And this is no longer magic, this is a clearly defined work of Scala. On which the programmer has to stumble constantly. And without knowledge of even the basics of Scala, it’s very difficult to figure out.
    Compare for fun:
    public static void index() {

    public static Result login() {
        return ok(

    The first piece of code is simpler, but you need to know and follow some conventions, and the second piece of code is more verbose, but you also need to know something and follow something. The second may be more flexible, but not simpler. I personally like the first one more.
    By the way, what do you think is loginin the second example? This is a class generated from scala template. Which appears only after compilation of this very scala template. Those. The IDE will complain that there is no such class or the method signatures do not match if you change something. After compilation, the complaints disappear, but using the IDE's hints becomes problematic.
    Playterre One was full of light-winged fairies and good spirits. In Playterra II there are only mechanical golems in which you can see each gear.

    Indisputable advantages

    Despite many oddities, if not to say flaws, Play 2.1 has a number of undeniable advantages.

    Work with forms and validation

    Very comfortable. Full support for JSR-303 (Bean Validation) plus the ability to add your own validate-method for specific checks. I will not rewrite the examples from the official documentation. You can see them perfectly here .
    For templates, there is built-in inputfield generation , and you can immediately generate markup for Twitter Bootstrap. The only pity is that for version 1.4. You have to write a custom generator (section Writing your own field constructor ).
    If Authenticity Token had not been removed and Twitter Bootstrap 2.3 fields were generated, then it would be almost ideal.

    Akka and other asynchronous things

    Local taverns and taverns have very fast service. And there are never queues.
    In terms of asynchrony and support for multithreading, Play 2.1 on horseback. There is native support for asynchronous HTTP requests and integration with Akka . If only Java verbosity wasn’t even mentioned in the official documentation when working with functions ...
    Just compare. Java:
    public static Result index() {
      Promise promiseOfInt = play.libs.Akka.future(
        new Callable() {
          public Integer call() {
            return intensiveComputation();
      return async(
          new Function() {
            public Result apply(Integer i) {
              return ok("Got result: " + i);

    def index = Action {
      val futureInt = scala.concurrent.Future { intensiveComputation() }
      Async { => Ok("Got result: " + i))

    Another reason to switch to Scala. Or something else, but more "functional" than Java.
    However, competitors are not asleep: in Grails 2.3 there will be very good support for asynchronous computing ( post on the official blog ). Moreover, asynchronous computing is more convenient for Groovy than for Java: support for closures plays a role.

    Scalability and clouds

    The land here is fertile and can feed almost any population. And clouds of various shapes and sizes are floating and floating in the sky.
    It is said that due to its asynchronous and stateless nature, Play 2.1 scales very well. So far, my project has not grown to such needs, so I can not confirm this from my own experience.
    Yes, and Play 2.x is supported by many cloud hosting services. Moreover, native support, i.e. no need to build a war file and deploy it under Tomcat / Jetty.
    If you still need to collect the war-file, then you can do this only with the help of a third-party plug-in .

    CoffeeScript and Less Support

    Small demons were tamed here, and now they are faithfully serving people.
    Native support for CoffeeScript and Less. I don’t even know what can be added or explained here. Conveniently. That's right. Even minified everything is nowhere simpler: just load .min.jsinstead .js.
    There were no problems with this yet.


    Customs at the entrance to Playterra II hired new workers. Although who cares, nobody sees their work anyway. Let them work well, then no one will pay attention to them.
    The console has become much more convenient and functional than it was for Play 1.2.x. But this is more to the credit of SBT (Scala Build Tool) than to Play 2.1 itself.
    From what came in handy, I want to mention commands starting with ~that are executed every time a source code change occurs. An example with ~testI cited above.

    What is the result?

    Going on vacation at Playterra II is interesting. The issue with migration there is still quite open.
    For myself, I made the following conclusions:
    • To use Play 2.1 to the fullest, you need to know Scala well.
    • Need to quickly write a web application in Java? Take Play 1.2.x. Or Grails. Groovy is not as hard to understand as Scala.
    • We need to learn Scala. It is to study, because the differences from Java and even Groovy are very significant.
    • Java is almost hopelessly behind other programming languages. Returning to writing code only in Java after I started to enjoy functional programming is very difficult. Maybe Java 8 will save the situation.

    [1] - honestly, integrating Spring into Play 2.1 is possible, it doesn’t even look very difficult . Those. Spring Data JPA and other projects from Spring Data can theoretically be added, but I have not found specific examples and articles on this subject. The hands themselves did not reach either.
    [2] - during the preparation of the article, he discovered that Java API for JSON Processing should be implemented for Java EE 7. Judging by this post on the Oracle blog, it will be more convenient and better than the given example. Close enough to JSON support in Groovy. Only this in the future.

    Also popular now: