Apr 21 2013

Play Framework 2.1: The Bloom is Off The Rose

Published by at 12:20 am under Java,play framework,Web

Update: This post has gotten a lot more attention than I expected and I just want to say to those reading: Thanks for stopping by!

On a recent project, my team evaluated several web frameworks for an upcoming web application. We chose The Play Framework. I was very attracted to its simplicity and the rapidity with which we could get things working. The Scala templates are also very powerful and much simpler (for me at least) than JSP templates. All in all it seemed like a match made in heaven. We were all really enjoying working with it. Unfortunately the honeymoon ended shortly thereafter.

The Documentation

One of the first things I noticed about Play is how sparse the documentation is. Examples are very basic, which is sometimes ok, but frequently not ok. Searching Google for documentation often returned results on the Play page, but for the wrong Play version. This is not a big deal for many Java APIs/Frameworks, but with Play? This leads me to the next point.

Massive Changes between Releases

It’s commonplace for API’s to have breaking changes between major versions. The Java world typically deprecates functionality at least a release ahead of removal/breakage, which is polite, but not strictly necessary. But Play has thrown caution to he wind and seems to be in a constant state of upheaval. Between 1.x and 2.x the framework changed dramatically. Most of the documentation from 1.x is completely invalid for working on 2.x. And plenty of the documentation from 2.0 is not valid for 2.1. I’m all for agility, but at a certain point I’d like stability in the API and app, so that I can upgrade with confidence.

Scala vs Java

Our Team chose to develop in Java for many reasons, not the least of which was time. None of us know Scala to the extent that we could be productive with it. Sure, we could learn it but that would take time: Time we didn’t have. There’s also the fact that we would be leaving this app for the staff to continue to support. As a consultant you always have to consider the aftermath of your departure. How easily will the staff (even the ones that have worked beside you) be able to add features or fix bugs when you leave? Java was the natural choice. But something I’ve noticed is that the Scala and Java APIs aren’t congruent. Of course there will be some differences, but I’ve noticed extra features in the Scala API that I’d like to use, but can’t (Wrapping requests, filtering, etc).

Immutable Everything

In recent versions of Play I’ve noticed that formerly mutable objects are now immutable. That’s great. It sure makes concurrent programming easier. But what if I need to modify something? For instance, Play gives you the ability to intercept HTTP requests as they come in. But the Request objects are immutable. Can I wrap/decorate a Request? Sure…if I’m using the Scala API. Another example is the Configuration object. In previous versions of Play you could update your configuration at runtime. That ability has also been taken away. So how could I convert the JSON on an incoming request body into a Java object and then put it back on the request for controllers to consume? How can I modify configuration after start-up so that devops can dynamically set passwords and other sensitive data? Good questions. I can’t find answers in the documentation or mailing lists.
(update on changing configuration)

Do It Yourself JSON Parsing

Maybe I’m spoiled having used other Java Frameworks, but I don’t expect to have to manually invoke the JSON serializer for simple POJOs. Jackson Mapper does an excellent job and many other Frameworks have integration for it. For instance in Spring or one of the JAX-RS implementations, you only need to set some annotations on a method and the JSON on the request body will be deserialized and passed to you automatically. Not so with Play. Sure Jackson Mapper is built in, but you still have to write boilerplate to serialize or deserialize your data. This isn’t a show-stopper, but it’s a rough edge that takes away from the conciseness of my code.

Deployment Woes

Many organizations have existing servers and deployment processes and are, understandably, slow to change. On a recent project, the client had a pretty standard set up: an Apache web server fronting a Tomcat Servlet container. They expected the build product to be a WAR, so Play’s standard way of deploying was not acceptable. The Play2War plugin served the purpose of converting our project to a WAR, but it also has some rough edges. Granted it’s not 1.0 yet, but there are no other alternatives as previous 1.x plugins are not compatible. Once we got that working, however, we quickly realized that the client’s needs were too dynamic for Play to handle. Their current application starts up with development DB information. Their devops deployment team runs a script that prompts them for passwords and then sends an HTTP POST to a non-public endpoint in the app that updates the DB and reloads The EntityManger. This seems to be impossible in Play because of the immutable Configuration and because there is no published way to reload the JPA helper class. I could technically maintain my own EntytManagerFactory, but why would I want to do that if there’s already JPA integration?

Take Away

It very well could be that the problems I’ve had with Play are a result of a difference in ideologies between Scala and Java programming. If that’s the case, fine, but the framework shouldn’t stop me from doing something without offering an alternative path or best practice. Maybe there are work-arounds for all of my problems, but I just couldn’t find them. I can read the source if need be, but it shouldn’t be a replacement for documentation. I’ve found that my colleagues and I spend way too much time trying to get something to work in Play that already works in Java EE or Grails. More often than not we’ve hit a dead end. And it’s not as if we didn’t do our homework. We did a fairly thorough spike in Play. We did discover the immutability issue then, but assumed that surely there must be a “Play way” of doing it. Regardless of the issues, I still enjoy developing in Play. For simple, 100% greenfield apps it’s very rewarding and productive to use. But unless I discover solutions to my problems, I’ll probably just use Grails or JEE for new JVM web apps.

Update: See my newest post on this topic.


29 responses so far

29 Responses to “Play Framework 2.1: The Bloom is Off The Rose”

  1. Damienon 23 Apr 2013 at 2:48 am

    Nice article.

    > The Play2War plugin … it also has some rough edges

    Can you be more precise ?

    Thanks

  2. Miloskovon 23 Apr 2013 at 10:18 am

    In short, means Play sucks for 99% of the projects. just 1% or less is “For simple, 100% greenfield app”.

    Nice review.

  3. Anonymouson 23 Apr 2013 at 11:22 am

    g8 comments

  4. Remoon 23 Apr 2013 at 11:51 am

    I couldn’t write it better! I’d really love to work with Play2 but unless they change the things you’ve mentioned I’m back at ASP.NET MVC..

  5. Tonyon 23 Apr 2013 at 3:12 pm

    @Damien: ThePlay2War module is good, and none of these things are deal-breakers, but there are just a few things that have cost me time. The Lay2War plugin was one of hte better things about my Play experience.

    1. When I remove application.context=/path/ it does not automatically detect the context path of the deployed war. I’ve also noticed that the root URL is different when running “play run” and when deploying the war. For some reason “play run” requires the trailing slash whereas the war deploy does not.
    2. Doesn’t work with TomEE 1.5.2+. Granted the plugin never claims to be compatible with TomEE, but would be nice.
    3. Deploys entire app into a JAR in WEB-INF/lib, which is fine if you never expect to change the properties after deploy, but many of my clients do. I had to create deployment script that unzips the JAR to WEB-INF/classes.
    4+ I know there were a couple more things, but they escape me If I remember then I’ll amend this post.

  6. Christianon 24 Apr 2013 at 2:19 am

    The documentation is indeed a bit sparse. Your problems with Play in Java EE environments exist because Play has a completely different approach without app servers. I like it very much, but you cannot run play application this way in some companies. If you want to become happy with play you should shift your mindset away from standard Java EE.

  7. virtualeyeson 24 Apr 2013 at 5:40 am

    @Miloskov
    ****
    In short, means Play sucks for 99% of the projects. just 1% or less is “For simple, 100% greenfield app”.
    ****

    Complete and utter nonsense.

    Show me a full stack MVC Scala framework better than Play.

    Using Java with Play, why? Can’t you see the writing on the wall? Play 1.x has been well and truly ditched; Java support remains, but only nominally compared to Scala, the basket into which Play team has placed all of their eggs.

    Learn Scala as you learn Play and it will all come together, quicker than you’d imagine.

    Now, obviously I’m pro-Play-Scala, but not 100% so. There are warts, route compilation time being the single biggest PITA (affecting both Scala and Java sides, AFAIK), followed by assets compilation (LESS and Coffeescript) which is horribly slow compared to 3rd party libs like Node.

    Documentation covers the basics and generally does the trick, but can be too sparse in some cases (like multi-project builds).

    Overall though, show me a better full stack Scala framework than Play — if you say Lift, then I’ll say good luck learning that framework if you have little to no Scala experience ;-)

  8. Damienon 24 Apr 2013 at 6:01 am

    @Tony

    > 1. When I remove application.context=/path/ it does not automatically
    > detect the context path of the deployed war.

    You’re right, this will be dynamic in the next version :)
    https://github.com/dlecan/play2-war-plugin/issues/145

    > 2. Doesn’t work with TomEE 1.5.2+

    Work is in progress. I can expect, at least, to understand why servlets are deployed twice.
    https://github.com/dlecan/play2-war-plugin/issues/149

    > 3. Deploys entire app into a JAR in WEB-INF/lib

    Feel free to submit an enhancement issue, we can think about a “jar-exploded” mode.
    https://github.com/dlecan/play2-war-plugin/issues

  9. Tonyon 24 Apr 2013 at 7:23 am

    @Christian: I pushed for deploying our app the “Play way”, but was essentially denied. Knowing what I know now, I would have advised the client differently knowing their restrictions.

  10. Tonyon 24 Apr 2013 at 7:49 am

    @virtualeyes: My team is willing to learn Scala, and some of us are in our spare time (I’m taking Martin Odersky’s class), but the client’s time-frame is demanding, which is why we committed only to Java. I completely agree with making things immutable because I’ve felt the pain of writing concurrent apps in Java on mutable state. I would love to know the “Scala way” of doing some of the things that I would like to do like request/response filtering/decorating. I realized this morning that I could work around this. It’s going to be a lot of boilerplate, but it will do that job. I’m planning on writing a small Java library including immutable request and response wrappers and factories. This should ease the pain I’m feeling in that area.

  11. Tonyon 24 Apr 2013 at 7:52 am

    @Damien: Thank you for your responses. I’ll get that issue created.

  12. Tonyon 24 Apr 2013 at 7:53 am

    Sorry about the slowness of the site. I apparently need to talk to my hosting provider to find out what’s going on.

  13. Nilanjan Raychaudhurion 24 Apr 2013 at 1:39 pm

    Hi,

    Disclaimer: I am member of the playframework team

    Now let me see whether I can provide some concrete feedback on the points raised in this post.

    First of all thanks for choosing Play framework

    - Documentation

    We are actively working on improving documentation. Last time I checked we have around 400 pages worth of documentation on various features of Play. I know we have a long way to go. I would recommend people to also look at the sample projects provided with Play and other open source projects published on github. There are also couple of very good books in progress. And as always I know the folks at mailing list and stackoverflow are very active in answering questions. Last but least we want community to get involved in documentation.

    - Massive Changes between Releases

    We don’t break compatibility between minor releases and the last major release was 2.1.0. You are right about breaking changes between 2.0.x and 2.1.x but those releases are apart for more than a year. We made the breaking changes to make the core of the framework more stable. No one is forced to update to 2.1 and I know clients that are still on 2.0.x. But incase you want to upgrade there is an easy migration path.

    http://www.playframework.com/documentation/2.1.1/Migration

    - Scala vs Java

    Both Scala and Java API has equal importance in Play. Some Play features like Iteratee and filters are not there in Java because it requires certain language features that Scala provide. We are waiting for Java 8 lambdas so that we can port these features to Java. I would still think Filters should be available in Java and we will provide that in future release. I am not sure I understand what do you mean by wrapping request?

    - Immutable Everything

    I am glad that you like immutability. By modifying request do you mean action composition?
    http://www.playframework.com/documentation/2.1.1/JavaActionsComposition

    You know you can always override the application.conf setting by passing -D command line arguments.This should be good for dev ops to provision Play applications.
    http://www.playframework.com/documentation/2.1.1/ProductionConfiguration

    - Do It Yourself JSON Parsing

    Well great thing about Play is you can plugin your awesome JSON library. No one is stopping you from directly using the Jackson API.

    - Deployment Woes
    I think others already pointed out the alternatives. We are very opinionated in this area. One of the core features of Play is its scalability and we don’t think traditional web containers can provide that.

    I hope it provided insight. Thanks for the writeup

  14. Nilanjan Raychaudhurion 24 Apr 2013 at 1:40 pm

    Oh one more thing. Play1 and Play2 are completely two different frameworks.

  15. Jackon 24 Apr 2013 at 4:53 pm

    Its all true. I really like the whole ‘idea’ of the Play framework but the documentation is TERRIBLE compared to other web application frameworks. And if professional team of paid developers are having these same problems I’m having it makes me think what chance to I have when I am working on a solo project…the amount of time it takes me to find an answer to a problem is going to multiples of the time it takes a team – and that is if there is even an answer to be found. It seems to me that Play is not really feasible for personal projects due to the enormous amount of time required to find answers.

    And what is the deal with having Scala only support for various features?? Is this a real bilingual framework or not….was the Java support just a ploy to sucker in users and generate interest, and now we can see it is being relegated to a second class language which does not bode well for the future.

    Any efficiency gained from the automatic refresh-reload compiling with Play is offset five fold by the time wasted searching for answers.

    What would completely solve the documentation problem would be if the Play devs or some advanced Play users released some form of open source application so we could all see how things can and should be done.

  16. Tonyon 24 Apr 2013 at 10:27 pm

    @Nilanjan: Thank you for taking the time to comment. I’d be very interested in your insight.

    - Immutable Everything

    Regarding wrapping/modifying a request, I mean adding something to it before it gets to to a controller. For instance, say you have a request coming in bound for Controller.someMethod(). Say the body of this request is JSON and you would like to convert that JSON to an Object and then put it back on the body for Controller.someMethod() to access. In a sense I’m trying to intercept requests coming in with JSON and deserialize the body, add the newly created object back onto the request and pass it along to the controller. Since the play.mvc.Http object hierarchy (which includes Request) and Response is immutable, I can’t accomplish this. Don’t get too caught up on this particular example. This is just something that I recently tried. Is there a Play Java paradigm for doing this kind of thing with Requests and Responses?

    Regarding the immutable configuration, I did suggest to my client that they use the -D option, but they found that unacceptable and for good reason. They are very high security, so clear text passwords are not allowed anywhere. In this case a password could easily obtained by running “ps -ef | grep play”.

    Thanks!

  17. James Roperon 25 Apr 2013 at 10:38 pm

    Hi Tony,

    I’m also on the Play team.

    With regards to request wrapping, your use case is quite valid. I think the biggest problem here is that we don’t document (yes, back to our documentation :) ) well enough some best practices here. There are a few ways to achieve what you want to achieve.

    The first is to use a custom body parser. This method could definitely be improved by us by adding a few useful helper functions, but you can use it today. Create a new class that implements play.mvc.BodyParser, and delegates to play.mvc.BodyParser.Json. Then implement the parser method to invoke the JSON body parser, and then call the returned body parsers map method (easiest way to implement the Scala function that you pass in is using the Akka helper class, akka.dispatch.Mapper), passing in a function that converts the RequestBody to your own implementation of RequestBody that holds the parsed body. Use this parser by using the @BodyParser.Of annotation, and use request().body().as(MyBody.class).yourMethodToAccessTheObject() to access the body. If it were me I’d wrap this in static helper method.

    The second method is to use the the HTTP context args map. Using action composition, bind the JSON to your object, and then put the object into Http.Context.args. Then write a helper method for getting this object out of the args. You might put this helper method into your own Controller abstract class that all your controllers extend.

    Cheers,

    James

  18. Miloskovon 25 Apr 2013 at 11:19 pm

    I hope the play people listens, Play have a lot of problems as the author said.

    One problem is the project turned into 2 sides the Scala side or the Java side they should choose just one path.

    The documentation is scattered all around and sometimes I want to learn something with the Java side but I get the Scala way.

    Make up your mind, I suggest play should be as Version 1, A Java frameworks but get some Scala goodies as the template. Java still the number one language for development, There still few projects or jobs with Scala.

    And soon Java 8 will have lambdas so we can have very good abstractions, not to the level of Scala but something like ASP.Net MVC for Java.

  19. Tonyon 26 Apr 2013 at 12:44 am

    @James: Thanks for your comments. Your first solution is pretty complex without an example or maybe a gist? I started to attempted it, but had issues because new BodyPerser.Json().map(…) returns play.api.mvc.BaodyParser<B>, which is obviously not the same as play.mvc.BodyParser. Once again I seem caught between Scala and Java with no idea how to proceed.

    The other example of putting it on the context map yielded better results for me although it seems rather inelegant compared to the way Spring, RESTEasy, et al do it: method injection.

    @Consumes(“application/json”)
    public Response createProductInJSON(Product product) {
    // product was deserialized from JSON to Java
    }

    If I can figure out a way to do it with a BodyParser that would seem to be much better.

    I also discovered that I could implement play.mvc.Content and do the serialization in that class for outgoing requests. Other than that I see no other way of doing it.

    Thanks again for your responses.

  20. Markuson 04 May 2013 at 10:09 pm

    This is an exact reason why Java technology is really going nowhere but down at the present time. The platform has become too fragmented and experimental and doesn’t consider the real world requirements of Java developers.

  21. Danon 14 May 2013 at 11:33 pm

    I think this is Horseradish. I am NOT on the Play team.

    The lesson you should have learned is not to try to teach a new dog old tricks. Play is not Grails, Spring, or anything else you’ve used in your career as a Java developer. I don’t think anyone can adopt a technology that’s truly new and be able to learn it on the fly while keeping clients as satisfied as they’ve ever been. This is a fantasy.

    A year ago I was in the same boat as you, except I had just graduated from college. I didn’t know Play and had only been using Scala for a few months. Perhaps my inexperience was an advantage because it freed me from any preconceived notions of what a framework should do and how. Instead I took my time, and carefully began working my way toward proficiency. My patient employer is now very pleased with the quality of my work, and the speed with which I am able to deliver it.

    I certainly tasted some frustration along the way, but in retrospect, this was more due to my own misunderstandings than issues with the framework. What I learned from this is that I had expected too much of myself, not the framework. Anyone with determination and an open mind can learn Play!

  22. Tonyon 15 May 2013 at 7:47 am

    Dan, thanks for your comments.

    I can tell you from my years of experience in the industry that you are wrong about people not being able to learn and apply a new tech on the fly to the satisfaction of a client. I’ve seen it happen when good people are involved. In fact, I’d say it’s happening now.

    In actuality, my client is very happy with the application so far. I understand your misconception that experience necessarily means rigidity, but thats likely due to the people you’ve worked with in the short time you’ve been in the industry. For the most part, the people I work with are very open to new ideas and on top of the latest ideas in computer science and SE. Most of them are consultants, and in the consulting game if you don’t stay at the forefront of technology you get left behind. This is very different from working at a company and building/supporting the same apps for 10 years. As a consultant you get way less leeway or patience. So the people who tend to succeed in this type of job are those who can adapt, think on their feet, and generally get stuff done.

    The bottom line for me is, can I get the job done well with Play? The answer is yes, but with caveats. This particular client has requirements (some of which were not evident up front) that make it more difficult. They require the ability to be able to set the DB password after startup. Play does not allow this out of the box and does not make it simple to accomplish. I’ve found a way, but it involves the use of plugins that replace the JPA and JDBC plugins. There are others, but I’ve found ways to work around them.

    What I have learned is, when I’m faced with a client that has rigid requirements that an app must fit into a traditional Java EE environment, think long and hard as to whether it’s worth going with Play. That’s not a dig on the framework. It’s just admitting that it has a niche where it works well, and traditional Java EE is not it, in my opinion.

  23. Galder Zamarreñoon 17 Jun 2013 at 4:58 am

    Hi Tony,

    If you’re interested in Play 2.1, but still want to deploy in an EE environment, you might want to look into Escalante (http://escalante.io/). We’re bringing Play 2.1 applications to an EE server (JBoss Application Server 7+ behind) in order to expose app server or EE services to Play 2.1 applications. It’s still in its infancy, but we’re hoping to further enhance these services in next releases. The benefit you’d get is that you’d be able to deploy Play 2.1 apps alongside other war/ee deployments and get them to interact with each other.

    Cheers,
    Galder

  24. Simonon 29 Jun 2013 at 5:29 am

    I completely agree do Dan.
    You need an open mind and have to be willing to give up some old paradigms. When I switched from Spring MVC to Play2/Scala I felt more productive right from the start. And learning Scala by learning Play is fun, if you come from Java it’s actually pretty smooth, and you can still use imperative style if you feel lost at some point.
    Ok, there could be more documentation, but the sample apps that come with the framework are excellent and cover a lot of common tasks.
    So far I’ve used the framework in 4 different projects, small to pretty large, scala and java.

    btw: I am NOT on the Play team.

  25. Roberton 20 Jul 2013 at 12:34 pm

    I agree, Scala made me go away, I didn’t chose that, so why did my framework do so? I’m still on 1.2, probably migrating to something else.

  26. […] Play: Play! Framework Un-features That Really Irk My Inner Geek Why I’m Moving Away from the Play Framework Play Framework 2.1: The Bloom is Off The Rose […]

  27. Peteron 01 Oct 2013 at 1:52 am

    I’d appriciate you told us where you ended.

  28. Tonyon 01 Oct 2013 at 5:28 am

    Peter, We used angular as out front-end technology and are considering doing away with Play and converting the back-end to a simple set of JAX-RS services. My feelings on the subject are that I may use Play for prototyping and small, simple apps, but I won’t recommend it for teams that aren’t proficient in scala. If I have time to learn Scala thoroughly enough to use in Play I may give Play another go because it seems like a lot of the things I complained about are only problems if you’re using Java. But as it stands now, I see Play as a Scala web framework with some Java functionality.

  29. Balázson 13 Nov 2013 at 9:46 am

    I can only agree with Tony.

    The documentation is clearly not the framework’s strongest point, and while I understand they work hard on that part, they’re not even close to what I’d like to see.

    That’s not the Play guys’ fault but the framework is simply not widespread enough. I’d like to see more blogs, open source examples and patterns that the other smarter than myself guys created, and it takes time. I like to come up with solutions but you cannot do that all by yourself, each tier, each aspect (testing, transaction handling, deployment), takes too much time.

    Let’s wait and see what this becomes in a year or so.

Trackback URI | Comments RSS

Leave a Reply